// // DKButtonCell.m // DarkKit // // Created by Chad Weider on 4/7/07. // Copyright (c) 2008 Chad Weider // Some rights reserved: // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the // use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software in a // product, an acknowledgment in the product documentation would be appreciated // but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source distribution. // #import "DKButtonCell.h" #import "NSBezierPath+PXRoundedRectangleAdditions.h" #import "CTGradient.h" @interface NSButtonCell (NSButtonCellPrivate) - (NSDictionary *)_textAttributes; - (int)_buttonType; @end @implementation DKButtonCell - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView { if([self bezelStyle] == NSRoundedBezelStyle) { NSRect buttonRect; float buttonHeight; float buttonXPad; float buttonYShift; float buttonBoxHeight; float cornerRadius = NSHeight(frame)/2; switch([self controlSize]) { case NSRegularControlSize: buttonXPad = 7; buttonYShift = 1; buttonBoxHeight = 25; buttonHeight = 20; break; case NSSmallControlSize: buttonXPad = 5; buttonYShift = 1; buttonBoxHeight = 21; buttonHeight = 17; break; case NSMiniControlSize: buttonXPad = 2; buttonYShift = 1; buttonBoxHeight = 17; buttonHeight = 14; break; } buttonRect = NSMakeRect(frame.origin.x+buttonXPad+.5, floorf(NSMidY(frame)-(buttonBoxHeight)/2)+buttonYShift+.5, frame.size.width-2*buttonXPad, buttonHeight); NSBezierPath *bezelPath = [NSBezierPath bezierPathWithRoundedRect:buttonRect cornerRadius:cornerRadius]; CTGradient *fillGradient; if(([self isHighlighted] && ([self highlightsBy] & (NSChangeGrayCellMask | NSChangeBackgroundCellMask | NSPushInCellMask))) || ([self state] == NSOnState && ([self showsStateBy] & (NSChangeGrayCellMask | NSChangeBackgroundCellMask | NSPushInCellMask)))) fillGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:.4 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:.2 alpha:1.0]]; else fillGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:.3 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:.0 alpha:1.0]]; [fillGradient fillBezierPath:bezelPath angle:90.0]; [bezelPath setLineWidth:1]; [[NSColor colorWithCalibratedWhite:1 alpha:1] set]; [bezelPath stroke]; } else if([self bezelStyle] == NSSmallSquareBezelStyle) { NSRect buttonRect = NSInsetRect(frame, 0, 1); [[NSColor whiteColor] set]; NSRectFill(buttonRect); CTGradient *fillGradient = [[[CTGradient alloc] init] autorelease]; if([self isHighlighted] && ([self highlightsBy] & NSPushInCellMask)) { fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.40 alpha:1.0] atPosition:.5]; fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.30 alpha:1.0] atPosition:.5]; } else if([self state] == NSOnState && ([self highlightsBy] & NSChangeBackgroundCellMask)) { fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.32 alpha:1.0] atPosition:.5]; fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.22 alpha:1.0] atPosition:.5]; } else { fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.15 alpha:1.0] atPosition:.5]; fillGradient = [fillGradient addColorStop:[NSColor colorWithCalibratedWhite:.05 alpha:1.0] atPosition:.5]; } [fillGradient fillRect:NSInsetRect(buttonRect, 1, 1) angle:90]; } else if([self bezelStyle] == NSShadowlessSquareBezelStyle) { NSRect buttonRect = frame; [[NSColor colorWithCalibratedWhite:.25 alpha:1.0] set]; NSRectFill(buttonRect); CTGradient *fillGradient; if([self isHighlighted] && ([self highlightsBy] & NSPushInCellMask)) { fillGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:.27 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:.37 alpha:1.0]]; } else if([self state] == NSOnState && ([self highlightsBy] & NSChangeBackgroundCellMask)) { fillGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:.23 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:.33 alpha:1.0]]; } else { fillGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:.08 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:.18 alpha:1.0]]; } buttonRect = NSInsetRect(buttonRect, 1, 1); [fillGradient fillRect:buttonRect angle:90]; CTGradient *highlightGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:1 alpha:.2] endingColor:[NSColor colorWithCalibratedWhite:1 alpha:.0]]; NSRect highlightRect; NSRect remainderRect; NSDivideRect(buttonRect, &highlightRect, &remainderRect, 2.5, NSMinYEdge); [highlightGradient fillRect:highlightRect angle:90]; CTGradient *shadowGradient = [CTGradient gradientWithBeginningColor:[NSColor colorWithCalibratedWhite:0 alpha:.4] endingColor:[NSColor colorWithCalibratedWhite:.0 alpha:.00]]; NSRect shadowRect; NSDivideRect(buttonRect, &shadowRect, &remainderRect, 2, NSMinXEdge); [shadowGradient fillRect:shadowRect angle:0]; NSDivideRect(buttonRect, &shadowRect, &remainderRect, 2, NSMaxXEdge); [shadowGradient fillRect:shadowRect angle:-180]; NSDivideRect(buttonRect, &shadowRect, &remainderRect, 2.5, NSMaxYEdge); [shadowGradient fillRect:shadowRect angle:-90]; } } - (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView { if([self _buttonType] == NSSwitchButton) { float pad; float checkOffX,checkOffY; float cornerRadius = 2; NSRect buttonRect; switch([self controlSize]) { case NSRegularControlSize: pad = 2; checkOffX = 2.5; checkOffY = 4; break; case NSSmallControlSize: pad = 3; checkOffX = 2.5; checkOffY = 4; break; case NSMiniControlSize: pad = 4; checkOffX = 1.5; checkOffY = 2.5; break; } buttonRect = NSInsetRect(frame,pad+.5,pad+.5); NSBezierPath *bezelPath = [NSBezierPath bezierPathWithRoundedRect:buttonRect cornerRadius:cornerRadius]; float dim = 0; if([self isHighlighted]) dim = 1; NSColor *startColor = [NSColor colorWithCalibratedWhite:(dim ? .4 : .3) alpha:([self isEnabled] ? 1 : .5)]; NSColor *endColor = [NSColor colorWithCalibratedWhite:(dim ? .2: 0) alpha:([self isEnabled] ? 1 : .5)]; CTGradient *backgroundGradient = [CTGradient gradientWithBeginningColor:startColor endingColor:endColor]; [backgroundGradient fillBezierPath:bezelPath angle:90.0]; [bezelPath setLineWidth:1]; [[NSColor colorWithCalibratedWhite:1 alpha:([self isEnabled] ? 1 : .5)] set]; [bezelPath stroke]; //Draw Check if([self state] == NSOnState) { NSRect checkRect = NSOffsetRect(buttonRect, checkOffX, -checkOffY); NSBezierPath *checkPath = [[NSBezierPath alloc] init]; [checkPath moveToPoint:NSMakePoint(NSMinX(checkRect), NSMidY(checkRect)+1)]; [checkPath lineToPoint:NSMakePoint(NSMinX(checkRect) + NSWidth(checkRect)*.3, NSMaxY(checkRect))]; [checkPath lineToPoint:NSMakePoint(NSMinX(checkRect) + NSWidth(checkRect)*.8, NSMinY(checkRect)+1)]; [[NSColor colorWithCalibratedWhite:0.75 alpha:([self isEnabled] ? 1 : .5)] set]; [checkPath setLineWidth:2]; [checkPath setLineJoinStyle:NSMiterLineJoinStyle]; [checkPath stroke]; } //Draw Dash else if([self state] == NSMixedState) { NSRect checkRect = NSIntegralRect(NSInsetRect(buttonRect, NSWidth(buttonRect)*.30, NSHeight(buttonRect)*.45)); [[NSColor colorWithCalibratedWhite:0.75 alpha:([self isEnabled] ? 1 : .5)] set]; NSRectFill(checkRect); } } else if([self _buttonType] == NSRadioButton) { float pad; float checkOffX,checkOffY; NSRect buttonRect; switch([self controlSize]) { case NSRegularControlSize: pad = 2; checkOffX = 2.5; checkOffY = 4; break; case NSSmallControlSize: pad = 3; checkOffX = 2.5; checkOffY = 4; break; case NSMiniControlSize: pad = 4; checkOffX = 1.5; checkOffY = 2.5; break; } buttonRect = NSInsetRect(frame,pad+.5,pad+.5); NSBezierPath *bezelPath = [NSBezierPath bezierPathWithOvalInRect:buttonRect]; float dim = 0; if([self isHighlighted] && !([self state] == NSOnState)) dim = 1; NSColor *startColor = [NSColor colorWithCalibratedWhite:(dim ? .4 : .3) alpha:([self isEnabled] ? 1 : .5)]; NSColor *endColor = [NSColor colorWithCalibratedWhite:(dim ? .2: 0) alpha:([self isEnabled] ? 1 : .5)]; CTGradient *backgroundGradient = [CTGradient gradientWithBeginningColor:startColor endingColor:endColor]; [backgroundGradient fillBezierPath:bezelPath angle:90.0]; [bezelPath setLineWidth:1]; [[NSColor colorWithCalibratedWhite:1 alpha:([self isEnabled] ? 1 : .5)] set]; [bezelPath stroke]; //Draw Dot if([self state] == NSOnState) { NSBezierPath *checkPath = [NSBezierPath bezierPathWithOvalInRect:NSMakeRect(NSMidX(buttonRect)-2, NSMidY(buttonRect)-2, 4, 4)]; [[NSColor colorWithCalibratedWhite:0.85 alpha:([self isEnabled] ? 1 : .5)] set]; [checkPath fill]; } //Draw Dash else if([self state] == NSMixedState) { NSRect checkRect = NSIntegralRect(NSInsetRect(buttonRect, NSWidth(buttonRect)*.30, NSHeight(buttonRect)*.45)); [[NSColor colorWithCalibratedWhite:0.75 alpha:([self isEnabled] ? 1 : .5)] set]; NSRectFill(checkRect); } } else [super drawImage:image withFrame:frame inView:controlView]; } - (NSDictionary *)_textAttributes { NSMutableDictionary *aDict = [[NSMutableDictionary alloc] init]; [aDict addEntriesFromDictionary:[super _textAttributes]]; [aDict setObject:[NSColor colorWithCalibratedWhite:DKTextWhite alpha:1] forKey:NSForegroundColorAttributeName]; return [aDict autorelease]; } @end