demux: mkv: handle WAVE_FORMAT_MPEG_ADTS_AAC
[vlc.git] / modules / gui / macosx / VLCHUDScroller.m
blob5fdfd2b7fdd80142ecc917541d0dc02640c6ee24
1 //
2 //  VLCHUDScroller.m
3 //  HUDScroller
4 //
5 //  Created by BinaryGod on 5/22/08.
6 //
7 //  Copyright (c) 2008, Tim Davis (BinaryMethod.com, binary.god@gmail.com)
8 //  All rights reserved.
9 //
10 //  Redistribution and use in source and binary forms, with or without modification,
11 //  are permitted provided that the following conditions are met:
13 //        Redistributions of source code must retain the above copyright notice, this
14 //    list of conditions and the following disclaimer.
16 //        Redistributions in binary form must reproduce the above copyright notice,
17 //    this list of conditions and the following disclaimer in the documentation and/or
18 //    other materials provided with the distribution.
20 //        Neither the name of the BinaryMethod.com nor the names of its contributors
21 //    may be used to endorse or promote products derived from this software without
22 //    specific prior written permission.
24 //    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
25 //    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 //    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 //    IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 //    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 //    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
30 //    OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 //    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 //    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 //    POSSIBILITY OF SUCH DAMAGE.
35 // Special thanks to Matt Gemmell (http://mattgemmell.com/) for helping me solve the
36 // transparent drawing issues.  Your awesome man!!!
38 #import "VLCHUDScroller.h"
39 #import "CompatibilityFixes.h"
41 @implementation VLCHUDScroller
43 - (instancetype)initWithCoder:(NSCoder *)coder
45     self = [super initWithCoder:coder];
46     if (self) {
47         _scrollerStroke = [NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 1.0f];
48         _scrollerKnobGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.631f green:0.639f blue:0.655f alpha:1.0f]
49                                                               endingColor:[NSColor colorWithDeviceRed:0.439f green:0.447f blue:0.471f alpha:1.0f]];
50         _scrollerTrackGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.137f green:0.137f blue:0.137f alpha:.75f]
51                                                                endingColor:[NSColor colorWithDeviceRed:0.278f green:0.278f blue:0.278f alpha:.75f]];
52         _scrollerArrowNormalGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:0.5f]
53                                                                      endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:0.5f]];
54         _scrollerArrowPushedGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.451f green:0.451f blue:0.455f alpha:0.5f]
55                                                                                                  endingColor:[NSColor colorWithDeviceRed:0.318f green:0.318f blue:0.318f alpha:0.5f]];
56     }
57     return self;
60 #pragma mark Drawing Functions
62 - (void)drawRect:(NSRect)rect {
63     if (OSX_YOSEMITE_AND_HIGHER) {
64         return [super drawRect:rect];
65     }
66     // See if we should use system default or supplied value
67     if ([self arrowsPosition] == NSScrollerArrowsDefaultSetting) {
68         arrowPosition = [[[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain] valueForKey: @"AppleScrollBarVariant"];
69         if (arrowPosition == nil) {
70             arrowPosition = @"DoubleMax";
71         }
72     } else {
73         if ([self arrowsPosition] == NSScrollerArrowsNone) {
74             arrowPosition = @"None";
75         }
76     }
78     NSDisableScreenUpdates();
80     [[NSColor colorWithCalibratedWhite:0.0f alpha:0.7f] set];
81     NSRectFill([self bounds]);
83     // Draw knob-slot.
84     [self drawKnobSlotInRect:[self bounds] highlight:YES];
86     // Draw knob
87     [self drawKnob];
89     // Draw arrows
90     [self drawArrow:NSScrollerIncrementArrow highlight:([self hitPart] == NSScrollerIncrementLine)];
91     [self drawArrow:NSScrollerDecrementArrow highlight:([self hitPart] == NSScrollerDecrementLine)];
93     [[self window] invalidateShadow];
95     NSEnableScreenUpdates();
98 - (void)drawKnob {
99     if (OSX_YOSEMITE_AND_HIGHER) {
100         return [super drawKnob];
101     }
103     if(![self isHoriz]) {
105         //Draw Knob
106         NSBezierPath *knob = [[NSBezierPath alloc] init];
107         NSRect knobRect = [self rectForPart:NSScrollerKnob];
110         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2)))
111                                          radius:(knobRect.size.width -2) /2
112                                      startAngle:180
113                                        endAngle:0];
115         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2)))
116                                          radius:(knobRect.size.width -2) /2
117                                      startAngle:0
118                                        endAngle:180];
120         [_scrollerStroke set];
121         [knob fill];
123         knobRect.origin.x += 1;
124         knobRect.origin.y += 1;
125         knobRect.size.width -= 2;
126         knobRect.size.height -= 2;
128         knob = [[NSBezierPath alloc] init];
130         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2)))
131                                          radius:(knobRect.size.width -2) /2
132                                      startAngle:180
133                                        endAngle:0];
135         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2)))
136                                          radius:(knobRect.size.width -2) /2
137                                      startAngle:0
138                                        endAngle:180];
140         [_scrollerKnobGradient drawInBezierPath:knob angle:0];
142     } else {
144         //Draw Knob
145         NSBezierPath *knob = [[NSBezierPath alloc] init];
146         NSRect knobRect = [self rectForPart:NSScrollerKnob];
148         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
149                                          radius:(knobRect.size.height -1) /2
150                                      startAngle:90
151                                        endAngle:270];
153         [knob appendBezierPathWithArcWithCenter:NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
154                                          radius:(knobRect.size.height -1) /2
155                                      startAngle:270
156                                        endAngle:90];
158         [_scrollerStroke set];
159         [knob fill];
161         knobRect.origin.x += 1;
162         knobRect.origin.y += 1;
163         knobRect.size.width -= 2;
164         knobRect.size.height -= 2;
166         knob = [[NSBezierPath alloc] init];
168         [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
169                                          radius:(knobRect.size.height -1) /2
170                                      startAngle:90
171                                        endAngle:270];
173         [knob appendBezierPathWithArcWithCenter:NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2)))
174                                          radius:(knobRect.size.height -1) /2
175                                      startAngle:270
176                                        endAngle:90];
178         [_scrollerKnobGradient drawInBezierPath:knob angle:90];
180     }
183 - (void)drawArrow:(NSScrollerArrow)arrow highlightPart:(NSUInteger)part {
184     if (OSX_YOSEMITE_AND_HIGHER) {
185         return [super drawArrow:arrow highlight:part];
186     }
188     if (arrow == NSScrollerDecrementArrow) {
190         if (part == (NSUInteger)-1 || part == 0) {
191             [self drawDecrementArrow: NO];
192         } else {
193             [self drawDecrementArrow: YES];
194         }
195     }
197     if (arrow == NSScrollerIncrementArrow) {
199         if(part == 1 || part == (NSUInteger)-1) {
201             [self drawIncrementArrow: NO];
202         } else {
204             [self drawIncrementArrow: YES];
205         }
206     }
209 - (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight {
210     if (OSX_YOSEMITE_AND_HIGHER) {
211         return [super drawKnobSlotInRect:rect highlight:highlight];
212     }
214     if (![self isHoriz]) {
216         // Draw Knob Slot
217         [_scrollerTrackGradient drawInRect:rect angle:0];
219         if ([arrowPosition isEqualToString:@"DoubleMax"]) {
221             // Adjust rect height for top base
222             rect.size.height = 8;
224             // Draw Top Base
225             NSBezierPath *path = [[NSBezierPath alloc] init];
226             NSPoint basePoints[4];
228             [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -5)
229                                              radius:(rect.size.width ) /2
230                                          startAngle:180
231                                            endAngle:0];
233             // Add the rest of the points
234             basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
235             basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y);
236             basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
237             basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
239             [path appendBezierPathWithPoints:basePoints count:4];
241             [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
243         } else if ([arrowPosition isEqualToString:@"None"]) {
245             // Adjust rect height for top base
246             NSRect topRect = rect;
247             topRect.size.height = 8;
249             // Draw Top Base
250             NSBezierPath *path = [[NSBezierPath alloc] init];
251             NSPoint basePoints[4];
253             [path appendBezierPathWithArcWithCenter:NSMakePoint(topRect.size.width /2, topRect.size.height + (topRect.size.width /2) -5)
254                                              radius:(topRect.size.width ) /2
255                                          startAngle:180
256                                            endAngle:0];
258             // Add the rest of the points
259             basePoints[3] = NSMakePoint( topRect.origin.x, topRect.origin.y + topRect.size.height);
260             basePoints[2] = NSMakePoint( topRect.origin.x, topRect.origin.y);
261             basePoints[1] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y);
262             basePoints[0] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y + topRect.size.height);
264             [path appendBezierPathWithPoints:basePoints count:4];
266             [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
269             // Draw Decrement Button
270             NSRect bottomRect = rect;
271             bottomRect.origin.y = rect.size.height - 4;
272             bottomRect.size.height = 4;
274             path = [[NSBezierPath alloc] init];
276             // Add Notch
277             [path appendBezierPathWithArcWithCenter:NSMakePoint((bottomRect.size.width ) /2, (bottomRect.origin.y  - ((bottomRect.size.width ) /2) + 1))
278                                              radius:(bottomRect.size.width ) /2
279                                          startAngle:0
280                                            endAngle:180];
282             // Add the rest of the points
283             basePoints[0] = NSMakePoint( bottomRect.origin.x, bottomRect.origin.y);
284             basePoints[1] = NSMakePoint( bottomRect.origin.x, bottomRect.origin.y + bottomRect.size.height);
285             basePoints[2] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y + bottomRect.size.height);
286             basePoints[3] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y);
288             // Add Points to Path
289             [path appendBezierPathWithPoints:basePoints count:4];
291             [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
292         }
293     } else {
295         // Draw Knob Slot
296         [_scrollerTrackGradient drawInRect:rect angle:90];
298         if ([arrowPosition isEqualToString:@"DoubleMax"]) {
300             // Adjust rect height for top base
301             rect.size.width = 8;
303             // Draw Top Base
304             NSBezierPath *path = [[NSBezierPath alloc] init];
305             NSPoint basePoints[4];
307             [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.height /2) +5, rect.origin.y + (rect.size.height /2) )
308                                              radius:(rect.size.height ) /2
309                                          startAngle:90
310                                            endAngle:270];
312             // Add the rest of the points
313             basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
314             basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y);
315             basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
316             basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
318             [path appendBezierPathWithPoints:basePoints count:4];
320             [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
321         } else if ([arrowPosition isEqualToString:@"None"]) {
323             // Adjust rect height for top base
324             NSRect topRect = rect;
325             topRect.size.width = 8;
327             // Draw Top Base
328             NSBezierPath *path = [[NSBezierPath alloc] init];
329             NSPoint basePoints[4];
331             [path appendBezierPathWithArcWithCenter:NSMakePoint((topRect.size.height /2) +5, topRect.origin.y + (topRect.size.height /2) )
332                                              radius:(topRect.size.height ) /2
333                                          startAngle:90
334                                            endAngle:270];
336             // Add the rest of the points
337             basePoints[2] = NSMakePoint( topRect.origin.x, topRect.origin.y + topRect.size.height);
338             basePoints[1] = NSMakePoint( topRect.origin.x, topRect.origin.y);
339             basePoints[0] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y);
340             basePoints[3] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y + topRect.size.height);
342             [path appendBezierPathWithPoints:basePoints count:4];
344             [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
346             // Bottom Base
347             // Draw Decrement Button
348             NSRect bottomRect = rect;
349             bottomRect.origin.x = rect.size.width - 4;
350             bottomRect.size.width = 4;
352             path = [[NSBezierPath alloc] init];
354             // Add Notch
355             [path appendBezierPathWithArcWithCenter:NSMakePoint(bottomRect.origin.x - ((bottomRect.size.height ) /2), (bottomRect.origin.y  + ((bottomRect.size.height ) /2) ))
356                                              radius:(bottomRect.size.height ) /2
357                                          startAngle:270
358                                            endAngle:90];
360             // Add the rest of the points
361             basePoints[3] = NSMakePoint( bottomRect.origin.x - (((bottomRect.size.height ) /2) -1), bottomRect.origin.y);
362             basePoints[0] = NSMakePoint( bottomRect.origin.x - (((bottomRect.size.height ) /2) -1), bottomRect.origin.y + bottomRect.size.height);
363             basePoints[1] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y + bottomRect.size.height);
364             basePoints[2] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y);
366             // Add Points to Path
367             [path appendBezierPathWithPoints:basePoints count:4];
369             [_scrollerArrowNormalGradient drawInBezierPath:path angle:90];
370         }
371     }
374 - (void)drawDecrementArrow:(bool)highlighted {
376     if (![self isHoriz]) {
378         if ([arrowPosition isEqualToString:@"DoubleMax"]) {
380             // Draw Decrement Button
381             NSRect rect = [self rectForPart: NSScrollerDecrementLine];
382             NSBezierPath *path = [[NSBezierPath alloc] init];
383             NSPoint basePoints[4];
385             // Add Notch
386             [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.width ) /2, (rect.origin.y  - ((rect.size.width ) /2) + 1))
387                                              radius:(rect.size.width ) /2
388                                          startAngle:0
389                                            endAngle:180];
391             // Add the rest of the points
392             basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y);
393             basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
394             basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
395             basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
397             // Add Points to Path
398             [path appendBezierPathWithPoints:basePoints count:4];
400             // Fill Path
401             if (!highlighted) {
402                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
403             } else {
404                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:0];
405             }
407             // Create Arrow Glyph
408             NSBezierPath *arrow = [[NSBezierPath alloc] init];
410             NSPoint points[3];
411             points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3);
412             points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) +3);
413             points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) +3);
415             [arrow appendBezierPathWithPoints:points count:3];
417             [_scrollerStroke set];
418             [arrow fill];
420             // Create Devider Line
421             [_scrollerStroke set];
423             [NSBezierPath strokeLineFromPoint:NSMakePoint(0, (rect.origin.y + rect.size.height) +.5f)
424                                       toPoint:NSMakePoint(rect.size.width, (rect.origin.y + rect.size.height) +.5f)];
426         } else if ([arrowPosition isEqualToString: @"Single"]) {
428             NSRect rect = [self rectForPart: NSScrollerDecrementLine];
430             NSBezierPath *path = [[NSBezierPath alloc] init];
431             NSPoint basePoints[4];
433             [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -3)
434                                              radius:(rect.size.width ) /2
435                                          startAngle:180
436                                            endAngle:0];
438             // Add the rest of the points
439             basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
440             basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y);
441             basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
442             basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
444             [path appendBezierPathWithPoints: basePoints count: 4];
446             // Fill Path
447             if (!highlighted) {
448                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
449             } else {
451                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:0];
452             }
454             // Create Arrow Glyph
455             NSBezierPath *arrow = [[NSBezierPath alloc] init];
457             NSPoint points[3];
458             points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3);
459             points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) +3);
460             points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) +3);
462             [arrow appendBezierPathWithPoints:points count:3];
464             [_scrollerStroke set];
465             [arrow fill];
466         }
467     } else {
469         if ([arrowPosition isEqualToString: @"DoubleMax"]) {
471             // Draw Decrement Button
472             NSRect rect = [self rectForPart:NSScrollerDecrementLine];
473             NSBezierPath *path = [[NSBezierPath alloc] init];
474             NSPoint basePoints[4];
476             // Add Notch
477             [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x - ((rect.size.height ) /2), (rect.origin.y  + ((rect.size.height ) /2) ))
478                                              radius:(rect.size.height ) /2
479                                          startAngle:270
480                                            endAngle:90];
482             // Add the rest of the points
483             basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y);
484             basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height);
485             basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
486             basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
488             // Add Points to Path
489             [path appendBezierPathWithPoints:basePoints count:4];
491             // Fill Path
492             if (!highlighted) {
493                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:90];
494             } else {
495                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:90];
496             }
498             // Create Arrow Glyph
499             NSBezierPath *arrow = [[NSBezierPath alloc] init];
501             NSPoint points[3];
502             points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2);
503             points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5f);
504             points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5f);
506             [arrow appendBezierPathWithPoints:points count:3];
508             [_scrollerStroke set];
509             [arrow fill];
511             // Create Devider Line
512             [_scrollerStroke set];
514             [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x + rect.size.width -.5f, rect.origin.y)
515                                       toPoint:NSMakePoint(rect.origin.x + rect.size.width -.5f, rect.origin.y + rect.size.height)];
517         } else if ([arrowPosition isEqualToString: @"Single"]) {
519             NSRect rect = [self rectForPart: NSScrollerDecrementLine];
521             NSBezierPath *path = [[NSBezierPath alloc] init];
522             NSPoint basePoints[4];
524             [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x + (rect.size.width -2) + ((rect.size.height ) /2), (rect.origin.y  + ((rect.size.height ) /2) ))
525                                              radius:(rect.size.height ) /2
526                                          startAngle:90
527                                            endAngle:270];
529             // Add the rest of the points
530             basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
531             basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y);
532             basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
533             basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
535             [path appendBezierPathWithPoints: basePoints count: 4];
537             // Fill Path
538             if (!highlighted) {
539                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:90];
540             } else {
541                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:90];
542             }
544             // Create Arrow Glyph
545             NSBezierPath *arrow = [[NSBezierPath alloc] init];
547             NSPoint points[3];
548             points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2);
549             points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5f);
550             points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5f);
552             [arrow appendBezierPathWithPoints:points count:3];
554             [_scrollerStroke set];
555             [arrow fill];
556         }
557     }
560 - (void)drawIncrementArrow:(bool)highlighted {
562     if (![self isHoriz]) {
564         if ([arrowPosition isEqualToString:@"DoubleMax"]) {
566             // Draw Increment Button
567             NSRect rect = [self rectForPart: NSScrollerIncrementLine];
569             if(!highlighted) {
571                 [_scrollerArrowNormalGradient drawInRect:rect angle:0];
572             } else {
574                 [_scrollerArrowPushedGradient drawInRect:rect angle:0];
575             }
577             // Create Arrow Glyph
578             NSBezierPath *arrow = [[NSBezierPath alloc] init];
580             NSPoint points[3];
581             points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3);
582             points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) -3);
583             points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) -3);
585             [arrow appendBezierPathWithPoints: points count: 3];
587             [_scrollerStroke set];
588             [arrow fill];
589         } else if ([arrowPosition isEqualToString:@"Single"]) {
591             // Draw Decrement Button
592             NSRect rect = [self rectForPart: NSScrollerIncrementLine];
593             NSBezierPath *path = [[NSBezierPath alloc] init];
594             NSPoint basePoints[4];
596             // Add Notch
597             [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.width ) /2, (rect.origin.y  - ((rect.size.width ) /2) + 2))
598                                              radius:(rect.size.width ) /2
599                                          startAngle:0
600                                            endAngle:180];
602             // Add the rest of the points
603             basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y);
604             basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height);
605             basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
606             basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
608             // Add Points to Path
609             [path appendBezierPathWithPoints:basePoints count:4];
611             // Fill Path
612             if (!highlighted) {
613                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
614             } else {
615                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:0];
616             }
618             // Create Arrow Glyph
619             NSBezierPath *arrow = [[NSBezierPath alloc] init];
621             NSPoint points[3];
622             points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3);
623             points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) -3);
624             points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) -3);
626             [arrow appendBezierPathWithPoints:points count:3];
628             [_scrollerStroke set];
629             [arrow fill];
630         }
631     } else {
633         if ([arrowPosition isEqualToString:@"DoubleMax"]) {
635             // Draw Increment Button
636             NSRect rect = [self rectForPart:NSScrollerIncrementLine];
638             if (!highlighted) {
639                 [_scrollerArrowNormalGradient drawInRect:rect angle:90];
640             } else {
641                 [_scrollerArrowPushedGradient drawInRect:rect angle:90];
642             }
644             // Create Arrow Glyph
645             NSBezierPath *arrow = [[NSBezierPath alloc] init];
647             NSPoint points[3];
648             points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2);
649             points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5f);
650             points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5f);
652             [arrow appendBezierPathWithPoints:points count:3];
654             [_scrollerStroke set];
655             [arrow fill];
656         } else if ([arrowPosition isEqualToString:@"Single"]) {
658             // Draw Decrement Button
659             NSRect rect = [self rectForPart:NSScrollerIncrementLine];
660             NSBezierPath *path = [[NSBezierPath alloc] init];
661             NSPoint basePoints[4];
663             // Add Notch
664             [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x - (((rect.size.height ) /2) -2), (rect.origin.y  + ((rect.size.height ) /2) ))
665                                              radius:(rect.size.height ) /2
666                                          startAngle:270
667                                            endAngle:90];
669             // Add the rest of the points
670             basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y);
671             basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height);
672             basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
673             basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y);
675             // Add Points to Path
676             [path appendBezierPathWithPoints:basePoints count:4];
678             // Fill Path
679             if (!highlighted) {
680                 [_scrollerArrowNormalGradient drawInBezierPath:path angle:0];
681             } else {
682                 [_scrollerArrowPushedGradient drawInBezierPath:path angle:0];
683             }
685             // Create Arrow Glyph
686             NSBezierPath *arrow = [[NSBezierPath alloc] init];
688             NSPoint points[3];
689             points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2);
690             points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5f);
691             points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5f);
693             [arrow appendBezierPathWithPoints:points count:3];
695             [_scrollerStroke set];
696             [arrow fill];
697         }
698     }
701 #pragma mark -
702 #pragma mark Helper Methods
703 - (NSUsableScrollerParts)usableParts {
704     if (OSX_YOSEMITE_AND_HIGHER) {
705         return [super usableParts];
706     }
708     if ([self arrowsPosition] != NSScrollerArrowsNone) {
710         if ([self isHoriz]) {
712             // Now Figure out if we can actually show all parts
713             CGFloat arrowSpace = NSWidth([self rectForPart: NSScrollerIncrementLine]) + NSWidth([self rectForPart: NSScrollerDecrementLine]) +
714                 NSMidY([self rectForPart: NSScrollerIncrementLine]);
715             CGFloat knobSpace = NSWidth([self rectForPart: NSScrollerKnob]);
717             if ((arrowSpace + knobSpace) > NSWidth([self bounds])) {
719                 if (arrowSpace > NSWidth([self bounds])) {
720                     return NSNoScrollerParts;
721                 } else {
722                     return NSOnlyScrollerArrows;
723                 }
724             }
726         } else {
728             // Now Figure out if we can actually show all parts
729             CGFloat arrowSpace = NSHeight([self rectForPart: NSScrollerIncrementLine]) + NSHeight([self rectForPart: NSScrollerDecrementLine]) +
730                 NSMidX([self rectForPart: NSScrollerIncrementLine]);
731             CGFloat knobSpace = NSHeight([self rectForPart: NSScrollerKnob]);
733             if ((arrowSpace + knobSpace) > NSHeight([self bounds])) {
735                 if (arrowSpace > NSHeight([self bounds])) {
736                     return NSNoScrollerParts;
737                 } else {
738                     return NSOnlyScrollerArrows;
739                 }
740             }
741         }
742     }
744     return NSAllScrollerParts;
747 - (bool)isHoriz {
748     if ([self bounds].size.width > [self bounds].size.height) {
749         return YES;
750     }
751     return NO;
754 @end