// // BGHUDButtonCell.m // BGHUDAppKit // // Created by BinaryGod on 5/25/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. #import "BGHUDButtonCell.h" @implementation BGHUDButtonCell #pragma mark Draw Functions @synthesize themeKey; -(id)init { self = [super init]; if(self) { self.themeKey = @"gradientTheme"; buttonType = 0; } return self; } -(id)initWithCoder:(NSCoder *)aDecoder { self = (BGHUDButtonCell *)[super initWithCoder: aDecoder]; if(self) { if([aDecoder containsValueForKey: @"themeKey"]) { self.themeKey = [aDecoder decodeObjectForKey: @"themeKey"]; } else { self.themeKey = @"gradientTheme"; } if([aDecoder containsValueForKey: @"BGButtonType"]) { buttonType = [aDecoder decodeIntegerForKey: @"BGButtonType"]; } else { buttonType = 0; } } return self; } -(void)encodeWithCoder: (NSCoder *)coder { [super encodeWithCoder: coder]; [coder encodeObject: self.themeKey forKey: @"themeKey"]; [coder encodeInt: (int)buttonType forKey: @"BGButtonType"]; } -(id)copyWithZone:(NSZone *) zone { BGHUDButtonCell *copy = [super copyWithZone: zone]; copy->themeKey = nil; [copy setThemeKey: [self themeKey]]; return copy; } - (void)setButtonType:(NSButtonType)aType { buttonType = aType; [super setButtonType: aType]; } -(void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { // Make sure our own height is right, and not using // a NSMatrix parents height. cellFrame.size.height = [self cellSize].height; switch ([self bezelStyle]) { case NSTexturedRoundedBezelStyle: [self drawTexturedRoundedButtonInFrame: cellFrame]; break; case NSRoundRectBezelStyle: [self drawRoundRectButtonInFrame: cellFrame]; break; case NSSmallSquareBezelStyle: [self drawSmallSquareButtonInFrame: cellFrame]; break; case NSRoundedBezelStyle: [self drawRoundedButtonInFrame: cellFrame]; break; case NSRecessedBezelStyle: [self drawRecessedButtonInFrame: cellFrame]; break; case NSRegularSquareBezelStyle: case NSThickSquareBezelStyle: case NSThickerSquareBezelStyle: case NSDisclosureBezelStyle: case NSShadowlessSquareBezelStyle: case NSCircularBezelStyle: case NSTexturedSquareBezelStyle: case NSHelpButtonBezelStyle: case NSRoundedDisclosureBezelStyle: case NSInlineBezelStyle: // Don't do anything, just to suppress compiler warning break; } if (buttonType == NSSwitchButton || buttonType == NSRadioButton) { if ([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: cellFrame inView: [self controlView]]; } } } -(NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView { NSRect textRect = frame; // Adjust Text Rect based on control type and size if(buttonType != NSSwitchButton && buttonType != NSRadioButton) { textRect.origin.x += 5; textRect.size.width -= 10; textRect.size.height -= 2; } NSMutableAttributedString *newTitle = [title mutableCopy]; //If button is set to show alternate title then //display alternate title if([self showsStateBy] == 0 && [self highlightsBy] == 1) { if([self isHighlighted]) { if([self alternateTitle]) { [newTitle setAttributedString: [self attributedAlternateTitle]]; } } } //If button is set to show alternate title then //display alternate title if([self showsStateBy] == 1 && [self highlightsBy] == 3) { if([self state] == 1) { if([self alternateTitle]) { [newTitle setAttributedString: [self attributedAlternateTitle]]; } } } //Make sure we aren't trying to edit an //empty string. if([newTitle length] > 0) { [newTitle beginEditing]; // Removed so Shadows could be used // TODO: Find out why I had this in here in the first place, no cosmetic difference /*[newTitle removeAttribute: NSShadowAttributeName range: NSMakeRange(0, [newTitle length])];*/ //Set text color based on button enabled state. if([self isEnabled]) { [newTitle addAttribute: NSForegroundColorAttributeName value: [NSColor whiteColor] range: NSMakeRange(0, [newTitle length])]; } else { [newTitle addAttribute: NSForegroundColorAttributeName value: [NSColor colorWithDeviceRed: 1 green: 1 blue: 1 alpha: 0.2f] range: NSMakeRange(0, [newTitle length])]; } [newTitle endEditing]; //Make the super class do the drawing [super drawTitle: newTitle withFrame: textRect inView: controlView]; } [newTitle release]; return textRect; } -(void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView { if([image isTemplate]) { [super drawImage: image withFrame: frame inView: controlView]; } else { if(buttonType == NSSwitchButton) { [self drawCheckInFrame: frame isRadio: NO]; } else if(buttonType == NSRadioButton) { [self drawCheckInFrame: frame isRadio: YES]; } else { //Setup per State and Highlight Settings if([self showsStateBy] == 0 && [self highlightsBy] == 1) { if([self isHighlighted]) { if([self alternateImage]) { image = [self alternateImage]; } } } if([self showsStateBy] == 1 && [self highlightsBy] == 3) { if([self state] == 1) { if([self alternateImage]) { image = [self alternateImage]; } } } //Calculate Image Position NSRect imageRect = frame; imageRect.size.height = [image size].height; imageRect.size.width = [image size].width; imageRect.origin.y += (frame.size.height /2) - (imageRect.size.height /2); //Setup Position switch ([self imagePosition]) { case NSImageLeft: imageRect.origin.x += 5; break; case NSImageOnly: imageRect.origin.x += (frame.size.width /2) - (imageRect.size.width /2); break; case NSImageRight: imageRect.origin.x = ((frame.origin.x + frame.size.width) - imageRect.size.width) - 5; break; case NSImageBelow: break; case NSImageAbove: break; case NSImageOverlaps: break; default: imageRect.origin.x += 5; break; } [image setFlipped: YES]; //Draw the image based on enabled state if([self isEnabled]) { [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceAtop fraction: 0.7f]; } else { [image drawInRect: imageRect fromRect: NSZeroRect operation: NSCompositeSourceAtop fraction: 0.2f]; } } } } -(void)drawTexturedRoundedButtonInFrame:(NSRect)frame { //Adjust Rect so strokes are true and //shadows are visible frame.origin.x += 1.5f; frame.origin.y += 0.5f; frame.size.width -= 3; frame.size.height -= 4; //Adjust Rect based on ControlSize so that //my controls match as closely to apples //as possible. switch ([self controlSize]) { case NSRegularControlSize: frame.origin.y += 1; break; case NSSmallControlSize: //frame.origin.y += 3; //frame.size.height += 2; break; case NSMiniControlSize: //frame.origin.y += 5; //frame.size.height += 1; break; } //Draw Outer-most ring NSBezierPath *path = [[NSBezierPath alloc] init]; [path appendBezierPathWithRoundedRect: frame xRadius: 4.0f yRadius: 4.0f]; //Save Graphics State [NSGraphicsContext saveGraphicsState]; if([self isEnabled]) { NSShadow *dropShadow = [[NSShadow alloc] init]; [dropShadow setShadowColor: [NSColor blackColor]]; [dropShadow setShadowBlurRadius: 2]; [dropShadow setShadowOffset: NSMakeSize( 0, -1)]; [dropShadow set]; [dropShadow release]; } //Draw Dark Border [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.5f] set]; [path setLineWidth: 1.0f]; [path stroke]; //Restore Graphics State [NSGraphicsContext restoreGraphicsState]; if([self isEnabled]) { //Draw Background if(([self showsStateBy] == 12 && [self highlightsBy] == 14) || ([self showsStateBy] == 12 && [self highlightsBy] == 12)) { if([self state] == 1) { NSGradient *highlightGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [highlightGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], 1.0f, nil] autorelease]; [normalGradient drawInBezierPath: path angle: 90]; } } else { if([self isHighlighted]) { NSGradient *pushedGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [pushedGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], 1.0f, nil] autorelease]; [normalGradient drawInBezierPath: path angle: 90]; } } } else { NSGradient *disabledNormalGradient = [[[NSGradient alloc] initWithStartingColor: [NSColor colorWithDeviceRed: 0.251f green: 0.251f blue: 0.255f alpha: 0.2f] endingColor: [NSColor colorWithDeviceRed: 0.118f green: 0.118f blue: 0.118f alpha: 0.2f]] autorelease]; [disabledNormalGradient drawInBezierPath: path angle: 90]; } //Draw Border if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path setLineWidth: 1.0f]; [path stroke]; //path = nil; [path release]; if([self imagePosition] != NSImageOnly) { [self drawTitle: [self attributedTitle] withFrame: frame inView: [self controlView]]; } if([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: frame inView: [self controlView]]; } } -(void)drawRoundRectButtonInFrame:(NSRect)frame { //Adjust Rect so strokes are true and //shadows are visible frame.origin.x += 1.5f; frame.size.width -= 3; //Adjust Rect based on ControlSize so that //my controls match as closely to apples //as possible. switch ([self controlSize]) { case NSRegularControlSize: frame.size.height -= 3; break; case NSSmallControlSize: frame.size.height -= 3; break; case NSMiniControlSize: frame.origin.y += 1; frame.size.height -= 5; break; } //Create Path NSBezierPath *path = [[NSBezierPath alloc] init]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 90 endAngle: 270]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 270 endAngle: 90]; [path closePath]; [NSGraphicsContext saveGraphicsState]; //Draw dark border color if([self isEnabled]) { NSShadow *dropShadow = [[NSShadow alloc] init]; [dropShadow setShadowColor: [NSColor blackColor]]; [dropShadow setShadowBlurRadius: 2]; [dropShadow setShadowOffset: NSMakeSize( 0, -1)]; [dropShadow set]; [dropShadow release]; } [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.5f] set]; [path stroke]; [NSGraphicsContext restoreGraphicsState]; if([self isEnabled]) { if(([self showsStateBy] == 12 && [self highlightsBy] == 14) || ([self showsStateBy] == 12 && [self highlightsBy] == 12)) { if([self state] == 1) { NSGradient *highlightGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [highlightGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], 1.0f, nil] autorelease]; [normalGradient drawInBezierPath: path angle: 90]; } } else { if([self isHighlighted]) { NSGradient *pushedGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [pushedGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], 1.0f, nil] autorelease]; [normalGradient drawInBezierPath: path angle: 90]; } } } else { NSGradient *disabledNormalGradient = [[[NSGradient alloc] initWithStartingColor: [NSColor colorWithDeviceRed: 0.251f green: 0.251f blue: 0.255f alpha: 0.2f] endingColor: [NSColor colorWithDeviceRed: 0.118f green: 0.118f blue: 0.118f alpha: 0.2f]] autorelease]; [disabledNormalGradient drawInBezierPath: path angle: 90]; } if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path setLineWidth: 1.0f]; [path stroke]; [path release]; if([self imagePosition] != NSImageOnly) { NSRect textFrame = frame; textFrame.origin.y += 1; [self drawTitle: [self attributedTitle] withFrame: textFrame inView: [self controlView]]; } if([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: frame inView: [self controlView]]; } } -(void)drawSmallSquareButtonInFrame:(NSRect)frame { //Adjust Rect so strokes are true and //shadows are visible frame.origin.x += 1.5f; frame.origin.y += 0.5f; frame.size.width -= 3; frame.size.height = [[self controlView] bounds].size.height - 3; //Draw Outer-most ring NSBezierPath *path = [[NSBezierPath alloc] init]; [path appendBezierPathWithRect: frame]; [NSGraphicsContext saveGraphicsState]; if([self isEnabled]) { NSShadow *dropShadow = [[NSShadow alloc] init]; [dropShadow setShadowColor: [NSColor blackColor]]; [dropShadow setShadowBlurRadius: 2]; [dropShadow setShadowOffset: NSMakeSize( 0, -1)]; [dropShadow set]; [dropShadow release]; } [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.5f] set]; [path setLineWidth: 1.0f]; [path stroke]; [NSGraphicsContext restoreGraphicsState]; //Draw Background if([self isEnabled]) { if(([self showsStateBy] == 12 && [self highlightsBy] == 14) || ([self showsStateBy] == 12 && [self highlightsBy] == 12)) { if([self state] == 1) { NSGradient *highlightComplexGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [highlightComplexGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalComplexGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [normalComplexGradient drawInBezierPath: path angle: 90]; } } else { if([self isHighlighted]) { NSGradient *pushedComplexGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [pushedComplexGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalComplexGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [normalComplexGradient drawInBezierPath: path angle: 90]; } } } else { NSGradient *disabledNormalComplexGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.2f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.2f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.2f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.2f], (CGFloat)1.0f, nil] autorelease]; [disabledNormalComplexGradient drawInBezierPath: path angle: 90]; } //Draw Border if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path setLineWidth: 1.0f]; [path stroke]; [path release]; if([self imagePosition] != NSImageOnly) { [self drawTitle: [self attributedTitle] withFrame: frame inView: [self controlView]]; } if([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: frame inView: [self controlView]]; } } -(void)drawRoundedButtonInFrame:(NSRect)frame { NSRect textFrame; //Adjust Rect so strokes are true and //shadows are visible frame.origin.x += .5f; frame.origin.y += .5f; frame.size.height -= 1; frame.size.width -= 1; //Adjust Rect based on ControlSize so that //my controls match as closely to apples //as possible. switch ([self controlSize]) { default: // Silence uninitialized variable warnings for textFrame fields. case NSRegularControlSize: frame.origin.x += 4; frame.origin.y += 4; frame.size.width -= 8; frame.size.height -= 12; textFrame = frame; break; case NSSmallControlSize: frame.origin.x += 4; frame.origin.y += 4; frame.size.width -= 8; frame.size.height -= 11; textFrame = frame; textFrame.origin.y += 1; break; case NSMiniControlSize: frame.origin.y -= 1; textFrame = frame; textFrame.origin.y += 1; break; } //Create Path NSBezierPath *path = [[NSBezierPath alloc] init]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 90 endAngle: 270]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 270 endAngle: 90]; [path closePath]; if([self isEnabled]) { if(([self showsStateBy] == 12 && [self highlightsBy] == 14) || ([self showsStateBy] == 12 && [self highlightsBy] == 12)) { if([self state] == 1) { [[NSColor colorWithDeviceRed: 0.941f green: 0.941f blue: 0.941f alpha: 0.7f] set]; [path fill]; } else { [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.7f] set]; [path fill]; } } else { if([self isHighlighted]) { [[NSColor colorWithDeviceRed: 0.941f green: 0.941f blue: 0.941f alpha: 0.7f] set]; [path fill]; } else { [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.7f] set]; [path fill]; } } } else { [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.2f] set]; } [path release]; if([self imagePosition] != NSImageOnly) { [self drawTitle: [self attributedTitle] withFrame: textFrame inView: [self controlView]]; } if([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: frame inView: [self controlView]]; } } -(void)drawCheckInFrame:(NSRect)frame isRadio:(BOOL)radio{ //Adjust by .5 so lines draw true frame.origin.x += .5f; frame.origin.y += .5f; if([[[self controlView] className] isEqualToString: @"NSMatrix"]) { NSMatrix* matrix = (NSMatrix*)[self controlView]; frame.origin.y += (BGCenterY([matrix bounds]) / [matrix numberOfRows]) - BGCenterY(frame); //frame.origin.x += 40; } else if(![[[[self controlView] superclass] className] isEqualToString: @"BGHUDTableView"] && ![[[[self controlView] superclass] className] isEqualToString: @"BGHUDOutlineView"] && ![[[self controlView] className] isEqualToString: @"BGHUDTableView"] && ![[[self controlView] className] isEqualToString: @"BGHUDOutlineView"]) { frame.origin.y += (BGCenterY([[self controlView] bounds]) - BGCenterY(frame)); } // Create Check Rect NSRect innerRect = frame; NSRect textRect = frame; //Make adjustments based on ControlSize //Set checkbox size if([self controlSize] == NSRegularControlSize) { innerRect.size.height = 12; innerRect.size.width = 13; innerRect.origin.y += 2; } else if([self controlSize] == NSSmallControlSize) { innerRect.size.height = 10; innerRect.size.width = 11; innerRect.origin.y += 3; } else { innerRect.size.height = 8; innerRect.size.width = 9; innerRect.origin.y += 5; } if(radio) { innerRect.size.height = innerRect.size.width; } // Determine Horizontal Placement switch ([self imagePosition]) { case NSImageLeft: //Make adjustments to horizontal placement //Create Text Rect so text is drawn properly if([self controlSize] == NSRegularControlSize) { innerRect.origin.x += 2; textRect.size.width -= (NSMaxX(innerRect) + 5); textRect.origin.x = (NSMaxX(innerRect) + 5); textRect.origin.y -= 2; } else if([self controlSize] == NSSmallControlSize) { innerRect.origin.x += 3; textRect.size.width -= (NSMaxX(innerRect) + 6); textRect.origin.x = (NSMaxX(innerRect) + 6); textRect.origin.y -= 1; } else { innerRect.origin.x += 4; textRect.size.width -= (NSMaxX(innerRect) + 4); textRect.origin.x = (NSMaxX(innerRect) + 4); } break; case NSImageOnly: //Adjust slightly so lines draw true, and center really is //center if([self controlSize] == NSRegularControlSize) { innerRect.origin.x -= .5f; } else if([self controlSize] == NSMiniControlSize) { innerRect.origin.x += .5f; } innerRect.origin.x += BGCenterX(frame) - BGCenterX(innerRect); break; case NSImageRight: if([self controlSize] == NSRegularControlSize) { innerRect.origin.x = (NSWidth(frame) - NSWidth(innerRect) - 1.5f) ; textRect.origin.x += 2; textRect.size.width = (NSMinX(innerRect) - NSMinX(textRect) - 5); textRect.origin.y -= 2; } else if([self controlSize] == NSSmallControlSize) { innerRect.origin.x = (NSWidth(frame) - NSWidth(innerRect) - 1.5f); textRect.origin.x += 2; textRect.size.width = (NSMinX(innerRect) - NSMinX(textRect) - 5); textRect.origin.y -= 1; } else { innerRect.origin.x = (NSWidth(frame) - NSWidth(innerRect) - 1.5f); textRect.origin.x += 2; textRect.size.width = (NSMinX(innerRect) - NSMinX(textRect) - 5); } break; case NSImageBelow: break; case NSImageAbove: break; case NSImageOverlaps: break; case NSNoImage: break; } // Create Rounded Rect Path NSBezierPath *path = [[NSBezierPath alloc] init]; if(radio) { [path appendBezierPathWithOvalInRect: innerRect]; } else { [path appendBezierPathWithRoundedRect: innerRect xRadius: 2 yRadius: 2]; } [NSGraphicsContext saveGraphicsState]; //Draw Shadow if([self isEnabled]) { NSShadow *dropShadow = [[NSShadow alloc] init]; [dropShadow setShadowColor: [NSColor blackColor]]; [dropShadow setShadowBlurRadius: 2]; [dropShadow setShadowOffset: NSMakeSize( 0, -1)]; [dropShadow set]; [dropShadow release]; } [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.5f] set]; [path stroke]; [NSGraphicsContext restoreGraphicsState]; // Determine Fill Color and Alpha Values if([self isEnabled]) { if([self isHighlighted]) { NSGradient *highlightGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.524f green: 0.531f blue: 0.547f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.445f green: 0.453f blue: 0.469f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.406f green: 0.414f blue: 0.433f alpha: 0.7f], (CGFloat).5, [NSColor colorWithDeviceRed: 0.339f green: 0.347f blue: 0.367f alpha: 0.7f], (CGFloat)1.0f, nil] autorelease]; [highlightGradient drawInBezierPath: path angle: 90]; } else { NSGradient *normalGradient = [[[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha: 0.7f], (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.7f], .5f, [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.7f], 1.0f, nil] autorelease]; [normalGradient drawInBezierPath: path angle: 90]; } } else { NSGradient *disabledNormalGradient = [[[NSGradient alloc] initWithStartingColor: [NSColor colorWithDeviceRed: 0.251f green: 0.251f blue: 0.255f alpha: 0.2f] endingColor: [NSColor colorWithDeviceRed: 0.118f green: 0.118f blue: 0.118f alpha: 0.2f]] autorelease]; [disabledNormalGradient drawInBezierPath: path angle: 90]; } // Draw Border if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path setLineWidth: 1.0f]; [path stroke]; [path release]; // Draw Glyphs for On/Off/Mixed States switch ([self state]) { case NSMixedState: path = [[NSBezierPath alloc] init]; NSPoint pointsMixed[2]; pointsMixed[0] = NSMakePoint(NSMinX(innerRect) + 3, NSMidY(innerRect)); pointsMixed[1] = NSMakePoint(NSMaxX(innerRect) - 3, NSMidY(innerRect)); [path appendBezierPathWithPoints: pointsMixed count: 2]; if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path setLineWidth: 2.0f]; [path stroke]; [path release]; break; case NSOnState: if(radio) { if([self controlSize] == NSRegularControlSize) { innerRect.origin.x += 4; innerRect.origin.y += 4; innerRect.size.width -= 8; innerRect.size.height -= 8; } else if([self controlSize] == NSSmallControlSize) { innerRect.origin.x += 3.5f; innerRect.origin.y += 3.5f; innerRect.size.width -= 7; innerRect.size.height -= 7; } else { innerRect.origin.x += 3; innerRect.origin.y += 3; innerRect.size.width -= 6; innerRect.size.height -= 6; } path = [[NSBezierPath alloc] init]; [path appendBezierPathWithOvalInRect: innerRect]; if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } [path fill]; [path release]; } else { path = [[NSBezierPath alloc] init]; NSPoint pointsOn[4]; pointsOn[0] = NSMakePoint(NSMinX(innerRect) + 3, NSMidY(innerRect) - 2); pointsOn[1] = NSMakePoint(NSMidX(innerRect), NSMidY(innerRect) + 2); pointsOn[2] = NSMakePoint(NSMidX(innerRect), NSMidY(innerRect) + 2); pointsOn[3] = NSMakePoint(NSMinX(innerRect) + NSWidth(innerRect) - 1, NSMinY(innerRect) - 2); [path appendBezierPathWithPoints: pointsOn count: 4]; if([self isEnabled]) { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } else { [[NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 0.7f] set]; } if([self controlSize] == NSMiniControlSize) { [path setLineWidth: 1.5f]; } else { [path setLineWidth: 2.0f]; } [path stroke]; [path release]; } break; } if([self imagePosition] != NSImageOnly) { if([self attributedTitle]) { [self drawTitle: [self attributedTitle] withFrame: textRect inView: [self controlView]]; } } } -(void)drawRecessedButtonInFrame:(NSRect)frame {//This part is not implemented so good as the codes from Timothy Davis, but we do need that NSRect textFrame; //Adjust Rect so strokes are true and //shadows are visible frame.origin.x += .5f; frame.origin.y += .5f; frame.size.height -= 1; frame.size.width -= 1; //Adjust Rect based on ControlSize so that //my controls match as closely to apples //as possible. switch ([self controlSize]) { default: // Silence uninitialized variable warnings for textFrame fields. case NSRegularControlSize: frame.origin.x += 1; frame.origin.y += 1; frame.size.width -= 2; frame.size.height -= 4; textFrame = frame; break; case NSSmallControlSize: frame.origin.x += 1; frame.origin.y += 1; frame.size.width -= 2; frame.size.height -= 3; textFrame = frame; textFrame.origin.y += 1; break; case NSMiniControlSize: frame.origin.y -= 1; textFrame = frame; textFrame.origin.y += 1; break; } //Create Path NSBezierPath *path = [[NSBezierPath alloc] init]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 90 endAngle: 270]; [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - BGCenterY(frame), NSMidY(frame) + 0.5f) radius: BGCenterY(frame) startAngle: 270 endAngle: 90]; [path closePath]; if([self isEnabled]) { if([self state] == 1) { [[NSColor colorWithDeviceRed: 0.941f green: 0.941f blue: 0.941f alpha: 0.7f] set]; [path fill]; isMouseIn = NO; } else { if(isMouseIn){ [[NSColor colorWithDeviceRed: 0.941f green: 0.941f blue: 0.941f alpha: 0.7f] set]; [path fill]; } else { [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.7f] set]; [path fill]; } } } else { [[NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.2f] set]; } [path release]; if([self imagePosition] != NSImageOnly) { [self drawTitle: [self attributedTitle] withFrame: textFrame inView: [self controlView]]; } if([self imagePosition] != NSNoImage) { [self drawImage: [self image] withFrame: frame inView: [self controlView]]; } } - (void)mouseEntered:(NSEvent *)event{ if ([self bezelStyle] == NSRecessedBezelStyle) { isMouseIn = YES; [self setHighlighted:YES]; } } - (void)mouseExited:(NSEvent *)event{ if ([self bezelStyle] == NSRecessedBezelStyle) { isMouseIn = NO; [self setHighlighted:NO]; } } #pragma mark - #pragma mark Helper Methods -(void)dealloc { [themeKey release]; [super dealloc]; } -(void)setValue:(id) value forKey:(NSString *) key { if([key isEqualToString: @"inspectedType"]) { if([(NSNumber *)value intValue] == 2) { buttonType = NSSwitchButton; } else if([(NSNumber *)value intValue] == 3) { buttonType = NSRadioButton; } else { buttonType = 0; } } [super setValue: value forKey: key]; } #pragma mark - @end