// // VLCHUDScroller.m // HUDScroller // // Created by BinaryGod on 5/22/08. // // Copyright (c) 2008, Tim Davis (BinaryMethod.com, binary.god@gmail.com) // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation and/or // other materials provided with the distribution. // // Neither the name of the BinaryMethod.com nor the names of its contributors // may be used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // Special thanks to Matt Gemmell (http://mattgemmell.com/) for helping me solve the // transparent drawing issues. Your awesome man!!! #import "VLCHUDScroller.h" #import "CompatibilityFixes.h" #import "NSGradient+VLCAdditions.h" @implementation VLCHUDScroller - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { _scrollerStroke = [NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 1.0f]; _scrollerKnobGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.631f green:0.639f blue:0.655f alpha:1.0f] endingColor:[NSColor colorWithDeviceRed:0.439f green:0.447f blue:0.471f alpha:1.0f]]; _scrollerTrackGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.137f green:0.137f blue:0.137f alpha:.75f] endingColor:[NSColor colorWithDeviceRed:0.278f green:0.278f blue:0.278f alpha:.75f]]; _scrollerArrowNormalGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:0.5f] endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:0.5f]]; _scrollerArrowPushedGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.451f green:0.451f blue:0.455f alpha:0.5f] endingColor:[NSColor colorWithDeviceRed:0.318f green:0.318f blue:0.318f alpha:0.5f]]; } return self; } #pragma mark Drawing Functions - (void)drawRect:(NSRect)rect { if (OSX_YOSEMITE_AND_HIGHER) { return [super drawRect:rect]; } // See if we should use system default or supplied value if ([self arrowsPosition] == NSScrollerArrowsDefaultSetting) { arrowPosition = [[[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain] valueForKey: @"AppleScrollBarVariant"]; if (arrowPosition == nil) { arrowPosition = @"DoubleMax"; } } else { if ([self arrowsPosition] == NSScrollerArrowsNone) { arrowPosition = @"None"; } } NSDisableScreenUpdates(); [[NSColor colorWithCalibratedWhite:0.0f alpha:0.7f] set]; NSRectFill([self bounds]); // Draw knob-slot. [self drawKnobSlotInRect:[self bounds] highlight:YES]; // Draw knob [self drawKnob]; // Draw arrows [self drawArrow:NSScrollerIncrementArrow highlight:([self hitPart] == NSScrollerIncrementLine)]; [self drawArrow:NSScrollerDecrementArrow highlight:([self hitPart] == NSScrollerDecrementLine)]; [[self window] invalidateShadow]; NSEnableScreenUpdates(); } - (void)drawKnob { if (OSX_YOSEMITE_AND_HIGHER) { return [super drawKnob]; } if(![self isHoriz]) { //Draw Knob NSBezierPath *knob = [[NSBezierPath alloc] init]; NSRect knobRect = [self rectForPart:NSScrollerKnob]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2))) radius:(knobRect.size.width -2) /2 startAngle:180 endAngle:0]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2))) radius:(knobRect.size.width -2) /2 startAngle:0 endAngle:180]; [_scrollerStroke set]; [knob fill]; knobRect.origin.x += 1; knobRect.origin.y += 1; knobRect.size.width -= 2; knobRect.size.height -= 2; knob = [[NSBezierPath alloc] init]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), (knobRect.origin.y + ((knobRect.size.width -2) /2))) radius:(knobRect.size.width -2) /2 startAngle:180 endAngle:0]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.width - .5f) /2), ((knobRect.origin.y + knobRect.size.height) - ((knobRect.size.width -2) /2))) radius:(knobRect.size.width -2) /2 startAngle:0 endAngle:180]; [_scrollerKnobGradient vlc_safeDrawInBezierPath:knob angle:0]; } else { //Draw Knob NSBezierPath *knob = [[NSBezierPath alloc] init]; NSRect knobRect = [self rectForPart:NSScrollerKnob]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2))) radius:(knobRect.size.height -1) /2 startAngle:90 endAngle:270]; [knob appendBezierPathWithArcWithCenter:NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2))) radius:(knobRect.size.height -1) /2 startAngle:270 endAngle:90]; [_scrollerStroke set]; [knob fill]; knobRect.origin.x += 1; knobRect.origin.y += 1; knobRect.size.width -= 2; knobRect.size.height -= 2; knob = [[NSBezierPath alloc] init]; [knob appendBezierPathWithArcWithCenter:NSMakePoint(knobRect.origin.x + ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2))) radius:(knobRect.size.height -1) /2 startAngle:90 endAngle:270]; [knob appendBezierPathWithArcWithCenter:NSMakePoint((knobRect.origin.x + knobRect.size.width) - ((knobRect.size.height - .5f) /2), (knobRect.origin.y + ((knobRect.size.height -1) /2))) radius:(knobRect.size.height -1) /2 startAngle:270 endAngle:90]; [_scrollerKnobGradient vlc_safeDrawInBezierPath:knob angle:90]; } } - (void)drawArrow:(NSScrollerArrow)arrow highlightPart:(NSUInteger)part { if (OSX_YOSEMITE_AND_HIGHER) { return [super drawArrow:arrow highlight:part]; } if (arrow == NSScrollerDecrementArrow) { if (part == (NSUInteger)-1 || part == 0) { [self drawDecrementArrow: NO]; } else { [self drawDecrementArrow: YES]; } } if (arrow == NSScrollerIncrementArrow) { if(part == 1 || part == (NSUInteger)-1) { [self drawIncrementArrow: NO]; } else { [self drawIncrementArrow: YES]; } } } - (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight { if (OSX_YOSEMITE_AND_HIGHER) { return [super drawKnobSlotInRect:rect highlight:highlight]; } if (![self isHoriz]) { // Draw Knob Slot [_scrollerTrackGradient drawInRect:rect angle:0]; if ([arrowPosition isEqualToString:@"DoubleMax"]) { // Adjust rect height for top base rect.size.height = 8; // Draw Top Base NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -5) radius:(rect.size.width ) /2 startAngle:180 endAngle:0]; // Add the rest of the points basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else if ([arrowPosition isEqualToString:@"None"]) { // Adjust rect height for top base NSRect topRect = rect; topRect.size.height = 8; // Draw Top Base NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint(topRect.size.width /2, topRect.size.height + (topRect.size.width /2) -5) radius:(topRect.size.width ) /2 startAngle:180 endAngle:0]; // Add the rest of the points basePoints[3] = NSMakePoint( topRect.origin.x, topRect.origin.y + topRect.size.height); basePoints[2] = NSMakePoint( topRect.origin.x, topRect.origin.y); basePoints[1] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y); basePoints[0] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y + topRect.size.height); [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; // Draw Decrement Button NSRect bottomRect = rect; bottomRect.origin.y = rect.size.height - 4; bottomRect.size.height = 4; path = [[NSBezierPath alloc] init]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint((bottomRect.size.width ) /2, (bottomRect.origin.y - ((bottomRect.size.width ) /2) + 1)) radius:(bottomRect.size.width ) /2 startAngle:0 endAngle:180]; // Add the rest of the points basePoints[0] = NSMakePoint( bottomRect.origin.x, bottomRect.origin.y); basePoints[1] = NSMakePoint( bottomRect.origin.x, bottomRect.origin.y + bottomRect.size.height); basePoints[2] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y + bottomRect.size.height); basePoints[3] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } } else { // Draw Knob Slot [_scrollerTrackGradient drawInRect:rect angle:90]; if ([arrowPosition isEqualToString:@"DoubleMax"]) { // Adjust rect height for top base rect.size.width = 8; // Draw Top Base NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.height /2) +5, rect.origin.y + (rect.size.height /2) ) radius:(rect.size.height ) /2 startAngle:90 endAngle:270]; // Add the rest of the points basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else if ([arrowPosition isEqualToString:@"None"]) { // Adjust rect height for top base NSRect topRect = rect; topRect.size.width = 8; // Draw Top Base NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint((topRect.size.height /2) +5, topRect.origin.y + (topRect.size.height /2) ) radius:(topRect.size.height ) /2 startAngle:90 endAngle:270]; // Add the rest of the points basePoints[2] = NSMakePoint( topRect.origin.x, topRect.origin.y + topRect.size.height); basePoints[1] = NSMakePoint( topRect.origin.x, topRect.origin.y); basePoints[0] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y); basePoints[3] = NSMakePoint( topRect.origin.x + topRect.size.width, topRect.origin.y + topRect.size.height); [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; // Bottom Base // Draw Decrement Button NSRect bottomRect = rect; bottomRect.origin.x = rect.size.width - 4; bottomRect.size.width = 4; path = [[NSBezierPath alloc] init]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint(bottomRect.origin.x - ((bottomRect.size.height ) /2), (bottomRect.origin.y + ((bottomRect.size.height ) /2) )) radius:(bottomRect.size.height ) /2 startAngle:270 endAngle:90]; // Add the rest of the points basePoints[3] = NSMakePoint( bottomRect.origin.x - (((bottomRect.size.height ) /2) -1), bottomRect.origin.y); basePoints[0] = NSMakePoint( bottomRect.origin.x - (((bottomRect.size.height ) /2) -1), bottomRect.origin.y + bottomRect.size.height); basePoints[1] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y + bottomRect.size.height); basePoints[2] = NSMakePoint( bottomRect.origin.x + bottomRect.size.width, bottomRect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:90]; } } } - (void)drawDecrementArrow:(bool)highlighted { if (![self isHoriz]) { if ([arrowPosition isEqualToString:@"DoubleMax"]) { // Draw Decrement Button NSRect rect = [self rectForPart: NSScrollerDecrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.width ) /2, (rect.origin.y - ((rect.size.width ) /2) + 1)) radius:(rect.size.width ) /2 startAngle:0 endAngle:180]; // Add the rest of the points basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:0]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3); points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) +3); points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) +3); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; // Create Devider Line [_scrollerStroke set]; [NSBezierPath strokeLineFromPoint:NSMakePoint(0, (rect.origin.y + rect.size.height) +.5f) toPoint:NSMakePoint(rect.size.width, (rect.origin.y + rect.size.height) +.5f)]; } else if ([arrowPosition isEqualToString: @"Single"]) { NSRect rect = [self rectForPart: NSScrollerDecrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.size.width /2, rect.size.height + (rect.size.width /2) -3) radius:(rect.size.width ) /2 startAngle:180 endAngle:0]; // Add the rest of the points basePoints[3] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); [path appendBezierPathWithPoints: basePoints count: 4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:0]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) -3); points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) +3); points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) +3); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; } } else { if ([arrowPosition isEqualToString: @"DoubleMax"]) { // Draw Decrement Button NSRect rect = [self rectForPart:NSScrollerDecrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x - ((rect.size.height ) /2), (rect.origin.y + ((rect.size.height ) /2) )) radius:(rect.size.height ) /2 startAngle:270 endAngle:90]; // Add the rest of the points basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height); basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:90]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:90]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2); points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5f); points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5f); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; // Create Devider Line [_scrollerStroke set]; [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x + rect.size.width -.5f, rect.origin.y) toPoint:NSMakePoint(rect.origin.x + rect.size.width -.5f, rect.origin.y + rect.size.height)]; } else if ([arrowPosition isEqualToString: @"Single"]) { NSRect rect = [self rectForPart: NSScrollerDecrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x + (rect.size.width -2) + ((rect.size.height ) /2), (rect.origin.y + ((rect.size.height ) /2) )) radius:(rect.size.height ) /2 startAngle:90 endAngle:270]; // Add the rest of the points basePoints[2] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); [path appendBezierPathWithPoints: basePoints count: 4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:90]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:90]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) -3, rect.size.height /2); points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) +3.5f); points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) +3, (rect.size.height /2) -3.5f); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; } } } - (void)drawIncrementArrow:(bool)highlighted { if (![self isHoriz]) { if ([arrowPosition isEqualToString:@"DoubleMax"]) { // Draw Increment Button NSRect rect = [self rectForPart: NSScrollerIncrementLine]; if(!highlighted) { [_scrollerArrowNormalGradient drawInRect:rect angle:0]; } else { [_scrollerArrowPushedGradient drawInRect:rect angle:0]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3); points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) -3); points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) -3); [arrow appendBezierPathWithPoints: points count: 3]; [_scrollerStroke set]; [arrow fill]; } else if ([arrowPosition isEqualToString:@"Single"]) { // Draw Decrement Button NSRect rect = [self rectForPart: NSScrollerIncrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint((rect.size.width ) /2, (rect.origin.y - ((rect.size.width ) /2) + 2)) radius:(rect.size.width ) /2 startAngle:0 endAngle:180]; // Add the rest of the points basePoints[0] = NSMakePoint( rect.origin.x, rect.origin.y); basePoints[1] = NSMakePoint( rect.origin.x, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); basePoints[3] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:0]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.size.width /2, rect.origin.y + (rect.size.height /2) +3); points[1] = NSMakePoint( (rect.size.width /2) +3.5f, rect.origin.y + (rect.size.height /2) -3); points[2] = NSMakePoint( (rect.size.width /2) -3.5f, rect.origin.y + (rect.size.height /2) -3); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; } } else { if ([arrowPosition isEqualToString:@"DoubleMax"]) { // Draw Increment Button NSRect rect = [self rectForPart:NSScrollerIncrementLine]; if (!highlighted) { [_scrollerArrowNormalGradient drawInRect:rect angle:90]; } else { [_scrollerArrowPushedGradient drawInRect:rect angle:90]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2); points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5f); points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5f); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; } else if ([arrowPosition isEqualToString:@"Single"]) { // Draw Decrement Button NSRect rect = [self rectForPart:NSScrollerIncrementLine]; NSBezierPath *path = [[NSBezierPath alloc] init]; NSPoint basePoints[4]; // Add Notch [path appendBezierPathWithArcWithCenter:NSMakePoint(rect.origin.x - (((rect.size.height ) /2) -2), (rect.origin.y + ((rect.size.height ) /2) )) radius:(rect.size.height ) /2 startAngle:270 endAngle:90]; // Add the rest of the points basePoints[3] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y); basePoints[0] = NSMakePoint( rect.origin.x - (((rect.size.height ) /2) -1), rect.origin.y + rect.size.height); basePoints[1] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y + rect.size.height); basePoints[2] = NSMakePoint( rect.origin.x + rect.size.width, rect.origin.y); // Add Points to Path [path appendBezierPathWithPoints:basePoints count:4]; // Fill Path if (!highlighted) { [_scrollerArrowNormalGradient vlc_safeDrawInBezierPath:path angle:0]; } else { [_scrollerArrowPushedGradient vlc_safeDrawInBezierPath:path angle:0]; } // Create Arrow Glyph NSBezierPath *arrow = [[NSBezierPath alloc] init]; NSPoint points[3]; points[0] = NSMakePoint( rect.origin.x + (rect.size.width /2) +3, rect.size.height /2); points[1] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) +3.5f); points[2] = NSMakePoint( rect.origin.x + (rect.size.height /2) -3, (rect.size.height /2) -3.5f); [arrow appendBezierPathWithPoints:points count:3]; [_scrollerStroke set]; [arrow fill]; } } } #pragma mark - #pragma mark Helper Methods - (NSUsableScrollerParts)usableParts { if (OSX_YOSEMITE_AND_HIGHER) { return [super usableParts]; } if ([self arrowsPosition] != NSScrollerArrowsNone) { if ([self isHoriz]) { // Now Figure out if we can actually show all parts CGFloat arrowSpace = NSWidth([self rectForPart: NSScrollerIncrementLine]) + NSWidth([self rectForPart: NSScrollerDecrementLine]) + NSMidY([self rectForPart: NSScrollerIncrementLine]); CGFloat knobSpace = NSWidth([self rectForPart: NSScrollerKnob]); if ((arrowSpace + knobSpace) > NSWidth([self bounds])) { if (arrowSpace > NSWidth([self bounds])) { return NSNoScrollerParts; } else { return NSOnlyScrollerArrows; } } } else { // Now Figure out if we can actually show all parts CGFloat arrowSpace = NSHeight([self rectForPart: NSScrollerIncrementLine]) + NSHeight([self rectForPart: NSScrollerDecrementLine]) + NSMidX([self rectForPart: NSScrollerIncrementLine]); CGFloat knobSpace = NSHeight([self rectForPart: NSScrollerKnob]); if ((arrowSpace + knobSpace) > NSHeight([self bounds])) { if (arrowSpace > NSHeight([self bounds])) { return NSNoScrollerParts; } else { return NSOnlyScrollerArrows; } } } } return NSAllScrollerParts; } - (bool)isHoriz { if ([self bounds].size.width > [self bounds].size.height) { return YES; } return NO; } @end