├── screenshots
└── custom-class.png
├── README.md
├── LICENSE
└── ScrollableSlider.swift
/screenshots/custom-class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thompsonate/Scrollable-NSSlider/HEAD/screenshots/custom-class.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scrollable-NSSlider
2 | `ScrollableSlider` is a subclass of NSSlider that accepts input from scrolling events. Apple doesn't support this natively, so this subclass was created to allow for scrolling input.
3 |
4 | `ScrollableSlider` supports vertical, horizontal, and circular NSSliders. It also accounts for natural scroll direction, so you'll be scrolling in the right direction regardless of your settings.
5 |
6 | # How to implement
7 | 1. Add the [ScrollableSlider](ScrollableSlider.swift) class to your code.
8 | 1. For any slider you want to operate with scrolling input, select it in Interface Builder and set the custom class to ScrollableSlider.
9 | 1. Scroll!
10 |
11 |
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/ScrollableSlider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollableSlider.swift
3 | //
4 | // Created by Nate Thompson on 10/24/17.
5 | //
6 | //
7 |
8 |
9 | import Cocoa
10 |
11 | class ScrollableSlider: NSSlider {
12 | override func scrollWheel(with event: NSEvent) {
13 | guard self.isEnabled else { return }
14 |
15 | let range = Float(self.maxValue - self.minValue)
16 | var delta = Float(0)
17 |
18 | // Allow horizontal scrolling on horizontal and circular sliders
19 | if _isVertical && self.sliderType == .linear {
20 | delta = Float(event.deltaY)
21 | } else if self.userInterfaceLayoutDirection == .rightToLeft {
22 | delta = Float(event.deltaY + event.deltaX)
23 | } else {
24 | delta = Float(event.deltaY - event.deltaX)
25 | }
26 |
27 | // Account for natural scrolling
28 | if event.isDirectionInvertedFromDevice {
29 | delta *= -1
30 | }
31 |
32 | let increment = range * delta / 100
33 | var value = self.floatValue + increment
34 |
35 | // Wrap around if slider is circular
36 | if self.sliderType == .circular {
37 | let minValue = Float(self.minValue)
38 | let maxValue = Float(self.maxValue)
39 |
40 | if value < minValue {
41 | value = maxValue - abs(increment)
42 | } else if value > maxValue {
43 | value = minValue + abs(increment)
44 | }
45 | }
46 |
47 | self.floatValue = value
48 | self.sendAction(self.action, to: self.target)
49 | }
50 |
51 |
52 | private var _isVertical: Bool {
53 | if #available(macOS 10.12, *) {
54 | return self.isVertical
55 | } else {
56 | // isVertical is an NSInteger in versions before 10.12
57 | return self.value(forKey: "isVertical") as! NSInteger == 1
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------