[vlc-devel] [PATCH 1/2] macosx: Add VLCDefaultValueSlider

Marvin Scholz epirat07 at gmail.com
Thu Dec 15 22:07:17 CET 2016


This is a new VLCDefaultSlider which allows setting a default
value, to which the knob will snap and a tick mark will be drawn for.
It's useful in VLC for things like volume sliders, which have a
default value (100%) to which we want the slider to snap.
Additionally this class is controllable with the scrollwheel by default.
---
 .../package/macosx/vlc.xcodeproj/project.pbxproj   |  12 ++
 modules/gui/macosx/Makefile.am                     |   4 +-
 modules/gui/macosx/VLCDefaultValueSlider.h         |  56 ++++++
 modules/gui/macosx/VLCDefaultValueSlider.m         |  78 +++++++
 modules/gui/macosx/VLCDefaultValueSliderCell.h     |  66 ++++++
 modules/gui/macosx/VLCDefaultValueSliderCell.m     | 224 +++++++++++++++++++++
 6 files changed, 439 insertions(+), 1 deletion(-)
 create mode 100644 modules/gui/macosx/VLCDefaultValueSlider.h
 create mode 100644 modules/gui/macosx/VLCDefaultValueSlider.m
 create mode 100644 modules/gui/macosx/VLCDefaultValueSliderCell.h
 create mode 100644 modules/gui/macosx/VLCDefaultValueSliderCell.m

diff --git a/extras/package/macosx/vlc.xcodeproj/project.pbxproj b/extras/package/macosx/vlc.xcodeproj/project.pbxproj
index 0dfd087..f986c83 100644
--- a/extras/package/macosx/vlc.xcodeproj/project.pbxproj
+++ b/extras/package/macosx/vlc.xcodeproj/project.pbxproj
@@ -419,6 +419,8 @@
 		6B3F8D2F1CE58E0E002A4998 /* VLCPreviousTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6B3F8D2B1CE58E0E002A4998 /* VLCPreviousTemplate.pdf */; };
 		6B3F8D311CE5CC21002A4998 /* VLCStatusBarIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6B3F8D301CE5CC21002A4998 /* VLCStatusBarIcon.pdf */; };
 		6B3F8D331CE5CD57002A4998 /* VLCShuffleTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6B3F8D321CE5CD57002A4998 /* VLCShuffleTemplate.pdf */; };
+		6B6A499E1DFD9B23009128AC /* VLCDefaultValueSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B6A499B1DFD9B23009128AC /* VLCDefaultValueSlider.m */; };
+		6B6A499F1DFD9B23009128AC /* VLCDefaultValueSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B6A499D1DFD9B23009128AC /* VLCDefaultValueSliderCell.m */; };
 		6B846FE41CF5D88C00112E54 /* VLCHUDButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B846FDD1CF5D88C00112E54 /* VLCHUDButtonCell.m */; };
 		6B846FE51CF5D88C00112E54 /* VLCHUDCheckboxCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B846FDF1CF5D88C00112E54 /* VLCHUDCheckboxCell.m */; };
 		6B846FE61CF5D88C00112E54 /* VLCHUDRadiobuttonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B846FE11CF5D88C00112E54 /* VLCHUDRadiobuttonCell.m */; };
@@ -1125,6 +1127,10 @@
 		6B3F8D2B1CE58E0E002A4998 /* VLCPreviousTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = VLCPreviousTemplate.pdf; path = Resources/vlcmenubaricon/VLCPreviousTemplate.pdf; sourceTree = "<group>"; };
 		6B3F8D301CE5CC21002A4998 /* VLCStatusBarIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = VLCStatusBarIcon.pdf; path = Resources/vlcmenubaricon/VLCStatusBarIcon.pdf; sourceTree = "<group>"; };
 		6B3F8D321CE5CD57002A4998 /* VLCShuffleTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = VLCShuffleTemplate.pdf; path = Resources/vlcmenubaricon/VLCShuffleTemplate.pdf; sourceTree = "<group>"; };
+		6B6A499A1DFD9B23009128AC /* VLCDefaultValueSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCDefaultValueSlider.h; path = ../../../modules/gui/macosx/VLCDefaultValueSlider.h; sourceTree = "<group>"; };
+		6B6A499B1DFD9B23009128AC /* VLCDefaultValueSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCDefaultValueSlider.m; path = ../../../modules/gui/macosx/VLCDefaultValueSlider.m; sourceTree = "<group>"; };
+		6B6A499C1DFD9B23009128AC /* VLCDefaultValueSliderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCDefaultValueSliderCell.h; path = ../../../modules/gui/macosx/VLCDefaultValueSliderCell.h; sourceTree = "<group>"; };
+		6B6A499D1DFD9B23009128AC /* VLCDefaultValueSliderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCDefaultValueSliderCell.m; path = ../../../modules/gui/macosx/VLCDefaultValueSliderCell.m; sourceTree = "<group>"; };
 		6B846FDC1CF5D88C00112E54 /* VLCHUDButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCHUDButtonCell.h; path = ../../../modules/gui/macosx/VLCHUDButtonCell.h; sourceTree = "<group>"; };
 		6B846FDD1CF5D88C00112E54 /* VLCHUDButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCHUDButtonCell.m; path = ../../../modules/gui/macosx/VLCHUDButtonCell.m; sourceTree = "<group>"; };
 		6B846FDE1CF5D88C00112E54 /* VLCHUDCheckboxCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCHUDCheckboxCell.h; path = ../../../modules/gui/macosx/VLCHUDCheckboxCell.h; sourceTree = "<group>"; };
@@ -1763,6 +1769,10 @@
 				6B846FE81CF5D89500112E54 /* HUD UI Classes */,
 				5CCED71414C0D4A90057F8D1 /* VLCUIWidgets.h */,
 				5CCED71514C0D4A90057F8D1 /* VLCUIWidgets.m */,
+				6B6A499A1DFD9B23009128AC /* VLCDefaultValueSlider.h */,
+				6B6A499B1DFD9B23009128AC /* VLCDefaultValueSlider.m */,
+				6B6A499C1DFD9B23009128AC /* VLCDefaultValueSliderCell.h */,
+				6B6A499D1DFD9B23009128AC /* VLCDefaultValueSliderCell.m */,
 				E0C2583E161B593D00185AAD /* VLCVoutWindowController.h */,
 				E0C2583F161B593D00185AAD /* VLCVoutWindowController.m */,
 				E06CF7F416020F6200C698B7 /* Windows.h */,
@@ -3556,6 +3566,7 @@
 				6B846FE51CF5D88C00112E54 /* VLCHUDCheckboxCell.m in Sources */,
 				1CCB5F6A1A62A724004C3E90 /* VLCExtensionsDialogProvider.h in Sources */,
 				7DBB06641CC2314D004C74D2 /* caopengllayer.m in Sources */,
+				6B6A499E1DFD9B23009128AC /* VLCDefaultValueSlider.m in Sources */,
 				1CCB5F6B1A62A724004C3E90 /* VLCExtensionsDialogProvider.m in Sources */,
 				1CCB5F6C1A62A724004C3E90 /* VLCExtensionsManager.h in Sources */,
 				1CCB5F6D1A62A724004C3E90 /* VLCExtensionsManager.m in Sources */,
@@ -3582,6 +3593,7 @@
 				1C67C8A81D58C0A40079E1C1 /* VLCAboutWindowController.m in Sources */,
 				1CCB5F801A62A724004C3E90 /* VLCPlaylistInfo.m in Sources */,
 				1CCB5F811A62A724004C3E90 /* prefs_widgets.h in Sources */,
+				6B6A499F1DFD9B23009128AC /* VLCDefaultValueSliderCell.m in Sources */,
 				1CCB5F821A62A724004C3E90 /* prefs_widgets.m in Sources */,
 				1CCB5F831A62A724004C3E90 /* prefs.h in Sources */,
 				1CCB5F841A62A724004C3E90 /* prefs.m in Sources */,
diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
index 2a0fcc8..9f5cc4f 100644
--- a/modules/gui/macosx/Makefile.am
+++ b/modules/gui/macosx/Makefile.am
@@ -88,4 +88,6 @@ libmacosx_plugin_la_SOURCES = \
 	VLCResumeDialogController.h VLCResumeDialogController.m \
 	VLCTrackSynchronizationWindowController.h VLCTrackSynchronizationWindowController.m \
 	VLCVideoEffectsWindowController.h VLCVideoEffectsWindowController.m \
-	VLCFSPanelController.h VLCFSPanelController.m
+	VLCFSPanelController.h VLCFSPanelController.m \
+	VLCDefaultValueSlider.h VLCDefaultValueSlider.m \
+	VLCDefaultValueSliderCell.h VLCDefaultValueSliderCell.m
diff --git a/modules/gui/macosx/VLCDefaultValueSlider.h b/modules/gui/macosx/VLCDefaultValueSlider.h
new file mode 100644
index 0000000..aa3fe84
--- /dev/null
+++ b/modules/gui/macosx/VLCDefaultValueSlider.h
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * VLCDefaultValueSlider.h: Custom NSSlider which allows a defaultValue
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 -at- gmail -dot- com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+/**
+ \c VLCDefaultValueSlider is a NSSlider subclass that allows setting
+ a \c defaultValue which gets a tickmark and the knob snaps to that
+ default value. Additionally a VLCDefaultValueSlider can be adjusted
+ with the mouse scroll wheel, if enabled.
+ */
+ at interface VLCDefaultValueSlider : NSSlider
+
+/**
+ Indicates if the slider is scrollable with the mouse or trackpad scrollwheel.
+ */
+ at property (readwrite) BOOL isScrollable;
+
+/**
+ Sets the default value to which the slider will snap and draw a tickmark for.
+ To unset the defaultValue, set it to \c DBL_MAX
+ 
+ \note value must be in the value range of the slider and be smaller than \c DBL_MAX
+ 
+ \param value The default value
+ */
+- (void)setDefaultValue:(double)value;
+
+/**
+ Get the default value
+ 
+ \note It the returned value is \c DBL_MAX, there is no defaultValue set.
+ */
+- (double)defaultValue;
+
+ at end
diff --git a/modules/gui/macosx/VLCDefaultValueSlider.m b/modules/gui/macosx/VLCDefaultValueSlider.m
new file mode 100644
index 0000000..aecb590
--- /dev/null
+++ b/modules/gui/macosx/VLCDefaultValueSlider.m
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * VLCDefaultValueSlider.m: Custom NSSlider which allows a defaultValue
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 -at- gmail -dot- com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCDefaultValueSlider.h"
+#import "VLCDefaultValueSliderCell.h"
+
+ at implementation VLCDefaultValueSlider
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+    if ([coder isKindOfClass: [NSKeyedUnarchiver class]]) {
+        NSKeyedUnarchiver *keyedUnarchiver = (id)coder;
+        NSString *oldClass = NSStringFromClass([self.superclass cellClass]);
+        [keyedUnarchiver setClass:[VLCDefaultValueSliderCell class] forClassName:oldClass];
+    }
+    self = [super initWithCoder:coder];
+    if (self) {
+        _isScrollable = YES;
+    }
+    return self;
+}
+
+- (void)scrollWheel:(NSEvent *)event
+{
+    if (!_isScrollable)
+        return [super scrollWheel:event];
+    double increment;
+    CGFloat deltaY = [event scrollingDeltaY];
+    double range = [self maxValue] - [self minValue];
+
+    // Scroll less for high precision, else it's too fast
+    if (event.hasPreciseScrollingDeltas) {
+        increment = (range * 0.002) * deltaY;
+    } else {
+        if (deltaY == 0.0)
+            return;
+        increment = (range * 0.01 * deltaY);
+    }
+
+    // If scrolling is inversed, increment in other direction
+    if (!event.isDirectionInvertedFromDevice)
+        increment = -increment;
+
+    [self setDoubleValue:self.doubleValue - increment];
+    [self sendAction:self.action to:self.target];
+}
+
+- (void)setDefaultValue:(double)value
+{
+    [(VLCDefaultValueSliderCell *)self.cell setDefaultValue:value];
+}
+
+- (double)defaultValue
+{
+    return [(VLCDefaultValueSliderCell *)self.cell defaultValue];
+}
+
+ at end
diff --git a/modules/gui/macosx/VLCDefaultValueSliderCell.h b/modules/gui/macosx/VLCDefaultValueSliderCell.h
new file mode 100644
index 0000000..a907faa
--- /dev/null
+++ b/modules/gui/macosx/VLCDefaultValueSliderCell.h
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * VLCDefaultValueSliderCell.h: SliderCell subclass for VLCDefaultValueSlider
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 -at- gmail -dot- com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+/**
+ \c VLCDefaultValueSliderCell is the cell use by the
+ \c VLCDefaultValueSlider class.
+ */
+ at interface VLCDefaultValueSliderCell : NSSliderCell
+
+/**
+ Indicates if a tickmark should be drawn for the \c defaultValue
+ */
+ at property (readwrite) BOOL drawTickMarkForDefault;
+
+/**
+ Indicates if the slider knob should snap to the \c defaultValue
+ */
+ at property (readwrite) BOOL snapsToDefault;
+
+/**
+ The default value of the slider
+ 
+ \note It may not be equal to \c DBL_MAX, as this is the value
+       that it should be set to, if no defaultValue is desired.
+ */
+ at property (getter=defaultValue, setter=setDefaultValue:) double defaultValue;
+
+/**
+ Color of the default tick mark
+ */
+ at property (getter=defaultTickMarkColor, setter=setDefaultTickMarkColor:) NSColor *defaultTickMarkColor;
+
+/**
+ Draws the tick mark for the \c defaultValue in the
+ given rect.
+ 
+ \note Override this in a subclass if you need to customize the
+ tickmark that is drawn for the \c defaultValue
+ 
+ \param rect The rect in which the tickMark should be drawn
+ */
+- (void)drawDefaultTickMarkWithFrame:(NSRect)rect;
+
+ at end
diff --git a/modules/gui/macosx/VLCDefaultValueSliderCell.m b/modules/gui/macosx/VLCDefaultValueSliderCell.m
new file mode 100644
index 0000000..e0d5c7a
--- /dev/null
+++ b/modules/gui/macosx/VLCDefaultValueSliderCell.m
@@ -0,0 +1,224 @@
+/*****************************************************************************
+ * VLCDefaultValueSliderCell.m: SliderCell subclass for VLCDefaultValueSlider
+ *****************************************************************************
+ * Copyright (C) 2016 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Marvin Scholz <epirat07 -at- gmail -dot- com>
+ *
+ * This file uses parts of code from the GNUstep NSSliderCell code:
+ * 
+ *   Copyright (C) 1996,1999 Free Software Foundation, Inc.
+ *   Author: Ovidiu Predescu <ovidiu at net-community.com>
+ *   Date: September 1997
+ *   Rewrite: Richard Frith-Macdonald <richard at brainstorm.co.uk>
+ *   Date: 1999
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCDefaultValueSliderCell.h"
+
+ at interface VLCDefaultValueSliderCell (){
+    BOOL _isRTL;
+    BOOL _isFlipped;
+    double _defaultValue;
+    NSColor *_defaultTickMarkColor;
+}
+ at end
+
+ at implementation VLCDefaultValueSliderCell
+
+#pragma mark -
+#pragma mark Public interface
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        [self setupSelf];
+    }
+    return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+    self = [super initWithCoder:coder];
+    if (self) {
+        [self setupSelf];
+    }
+    return self;
+}
+
+- (void)setDefaultValue:(double)value
+{
+    if (value > _maxValue || value < _minValue)
+        value = DBL_MAX;
+
+    if (_defaultValue == DBL_MAX && value != DBL_MAX) {
+        _drawTickMarkForDefault = YES;
+        _snapsToDefault = YES;
+    } else if (value == DBL_MAX) {
+        _drawTickMarkForDefault = NO;
+        _snapsToDefault = NO;
+    }
+    _defaultValue = value;
+    [[self controlView] setNeedsDisplay:YES];
+}
+
+- (double)defaultValue
+{
+    return _defaultValue;
+}
+
+- (void)setDefaultTickMarkColor:(NSColor *)color
+{
+    _defaultTickMarkColor = color;
+    [[self controlView] setNeedsDisplay:YES];
+
+}
+
+- (NSColor *)defaultTickMarkColor
+{
+    return _defaultTickMarkColor;
+}
+
+- (void)drawDefaultTickMarkWithFrame:(NSRect)rect
+{
+    [_defaultTickMarkColor setFill];
+    NSRectFill(rect);
+}
+
+#pragma mark -
+#pragma mark Internal helpers
+
+- (void)setupSelf
+{
+    _defaultValue = DBL_MAX;
+    _isRTL = ([self userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft);
+    _isFlipped = [[self controlView] isFlipped];
+    _defaultTickMarkColor = [NSColor grayColor];
+}
+
+/*
+ * Adapted from GNUstep NSSliderCell
+ * - (NSRect)knobRectFlipped:(BOOL)flipped
+ *
+ * Calculates the knobRect for a given position
+ * This is later used to draw the default tick mark in the center of
+ * where the knob would be, when it is at the default value.
+ */
+- (NSRect)knobRectFlipped:(BOOL)flipped forValue:(double)doubleValue
+{
+    NSRect superRect = [super knobRectFlipped:flipped];
+    NSPoint	origin;
+    NSSize size = superRect.size;
+
+    if ([self isVertical] && flipped) {
+        doubleValue = _maxValue + _minValue - doubleValue;
+    }
+
+    doubleValue = (doubleValue - _minValue) / (_maxValue - _minValue);
+
+    if ([self isVertical] == YES) {
+        origin = _trackRect.origin;
+        origin.x = superRect.origin.x;
+        origin.y += (_trackRect.size.height - size.height) * doubleValue;
+    } else {
+        origin = _trackRect.origin;
+        origin.y = superRect.origin.y;
+        origin.x += ((_trackRect.size.width - size.width) * doubleValue);
+    }
+
+    return NSMakeRect(origin.x, origin.y, size.width, size.height);
+}
+
+#pragma mark -
+#pragma mark Overwritten super methods
+
+- (NSRect)knobRectFlipped:(BOOL)flipped
+{
+    return [self knobRectFlipped:flipped forValue:[self doubleValue]];
+}
+
+- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
+{
+    // Do all other drawing
+    [super drawWithFrame:cellFrame inView:controlView];
+
+    // Default tick mark
+    if (_drawTickMarkForDefault && _defaultValue != DBL_MAX) {
+
+        // Calculate rect for default tick mark
+        CGFloat tickThickness = 1.0;
+
+        NSRect tickFrame = [self knobRectFlipped:_isFlipped
+                                        forValue:_defaultValue];
+
+        if ([self isVertical]) {
+            CGFloat mid = NSMidY(tickFrame);
+            tickFrame.origin.x = cellFrame.origin.x;
+            tickFrame.origin.y = mid - tickThickness/2.0;
+            tickFrame.size.width = cellFrame.size.width;
+            tickFrame.size.height = tickThickness;
+        } else {
+            CGFloat mid = NSMidX(tickFrame);
+            tickFrame.origin.x = mid - tickThickness/2.0;
+            tickFrame.origin.y = cellFrame.origin.y;
+            tickFrame.size.width = tickThickness;
+            tickFrame.size.height = cellFrame.size.height;
+        }
+
+        // Draw default tick mark
+        [self drawDefaultTickMarkWithFrame:tickFrame];
+    }
+
+    // Redraw knob
+    [super drawKnob];
+}
+
+- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
+{
+    double oldValue = [self doubleValue];
+    BOOL result = [super continueTracking:lastPoint at:currentPoint inView:controlView];
+    double newValue = [self doubleValue];
+
+    // If no change, nothing to do.
+    if (newValue == oldValue)
+        return result;
+
+    // Determine in which direction slider is moving
+    BOOL sliderMovingForward = YES;
+    if (oldValue > newValue) {
+        sliderMovingForward = NO;
+    }
+
+    // Calculate snap-threshhold
+    double range = self.maxValue - self.minValue;
+    double thresh = (range * 0.01) * 7;
+
+    // Snap to default value
+    if (ABS(newValue - _defaultValue) < thresh && _snapsToDefault) {
+        if (sliderMovingForward && newValue > _defaultValue) {
+            [self setDoubleValue: _defaultValue];
+        } else if (!sliderMovingForward && newValue < _defaultValue) {
+            [self setDoubleValue: _defaultValue];
+        }
+    }
+
+    return result;
+}
+
+ at end
-- 
2.10.1 (Apple Git-78)



More information about the vlc-devel mailing list