From 25f131ed4f18cd8dc9500ab4e18336ffbc852d29 Mon Sep 17 00:00:00 2001 From: Riccardo Canalicchio Date: Sat, 21 Dec 2013 15:18:13 +0100 Subject: [PATCH] NSWindow glossy buttons --- GNUmakefile | 6 +- GSStandardDecorationView+Rik.m | 40 +++++++++++++ NSWindow+Rik.m | 60 +++++++++++++++++++ RikWindowButton.h | 14 +++++ RikWindowButton.m | 23 ++++++++ RikWindowButtonCell.h | 12 ++++ RikWindowButtonCell.m | 103 +++++++++++++++++++++++++++++++++ 7 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 GSStandardDecorationView+Rik.m create mode 100644 NSWindow+Rik.m create mode 100644 RikWindowButton.h create mode 100644 RikWindowButton.m create mode 100644 RikWindowButtonCell.h create mode 100644 RikWindowButtonCell.m diff --git a/GNUmakefile b/GNUmakefile index 62313f1..fa00cef 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -12,7 +12,11 @@ Rik_OBJC_FILES = \ Rik.m\ Rik+Drawings.m\ Rik+Button.m\ - Rik+WindowDecoration.m + Rik+WindowDecoration.m\ + GSStandardDecorationView+Rik.m\ + NSWindow+Rik.m\ + RikWindowButton.m\ + RikWindowButtonCell.m ADDITIONAL_TOOL_LIBS = -lopal $(BUNDLE_NAME)_RESOURCE_FILES = \ diff --git a/GSStandardDecorationView+Rik.m b/GSStandardDecorationView+Rik.m new file mode 100644 index 0000000..a93bd3d --- /dev/null +++ b/GSStandardDecorationView+Rik.m @@ -0,0 +1,40 @@ +#import +#import + +#define TITLEBAR_BUTTON_SIZE 15 +#define TITLEBAR_PADDING_LEFT 10.5 +#define TITLEBAR_PADDING_RIGHT 10.5 +#define TITLEBAR_PADDING_TOP 5.5 +@interface GSStandardWindowDecorationView(RikTheme) + +@end + +@implementation GSStandardWindowDecorationView(RikTheme) +- (void) updateRects +{ + GSTheme *theme = [GSTheme theme]; + if (hasTitleBar) + { + CGFloat titleHeight = [theme titlebarHeight]; + titleBarRect = NSMakeRect(0.0, [self bounds].size.height - titleHeight, + [self bounds].size.width, titleHeight); + } + if (hasResizeBar) + { + resizeBarRect = NSMakeRect(0.0, 0.0, [self bounds].size.width, [theme resizebarHeight]); + } + if (hasCloseButton) + { + closeButtonRect = NSMakeRect( + [self bounds].size.width - TITLEBAR_BUTTON_SIZE - TITLEBAR_PADDING_RIGHT, [self bounds].size.height - TITLEBAR_BUTTON_SIZE - TITLEBAR_PADDING_TOP, TITLEBAR_BUTTON_SIZE, TITLEBAR_BUTTON_SIZE); + [closeButton setFrame: closeButtonRect]; + } + if (hasMiniaturizeButton) + { + miniaturizeButtonRect = NSMakeRect( + TITLEBAR_PADDING_LEFT, [self bounds].size.height - TITLEBAR_BUTTON_SIZE - TITLEBAR_PADDING_TOP, TITLEBAR_BUTTON_SIZE, TITLEBAR_BUTTON_SIZE); + [miniaturizeButton setFrame: miniaturizeButtonRect]; + } +} + +@end diff --git a/NSWindow+Rik.m b/NSWindow+Rik.m new file mode 100644 index 0000000..da6cb49 --- /dev/null +++ b/NSWindow+Rik.m @@ -0,0 +1,60 @@ +#import +#include "RikWindowButton.h" + + +@interface NSWindow(RikTheme) + +@end + +@implementation NSWindow(RikTheme) + ++ (NSButton *) standardWindowButton: (NSWindowButton)button + forStyleMask: (NSUInteger) mask +{ + NSButton *newButton; + + switch (button) + { + case NSWindowCloseButton: + newButton = [[RikWindowButton alloc] init]; + [(RikWindowButton*)newButton setBaseColor: [NSColor colorWithCalibratedRed: 0.698 green: 0.427 blue: 1.00 alpha: 1]]; + [newButton setImage: [NSImage imageNamed: @"common_Close"]]; + [newButton setAlternateImage: [NSImage imageNamed: @"common_CloseH"]]; + [newButton setAction: @selector(performClose:)]; + break; + + case NSWindowMiniaturizeButton: + newButton = [[RikWindowButton alloc] init]; + [newButton setBaseColor: [NSColor colorWithCalibratedRed: 0.9 green: 0.7 blue: 0.3 alpha: 1]]; + [newButton setImage: [NSImage imageNamed: @"common_Miniaturize"]]; + [newButton setAlternateImage: [NSImage imageNamed: @"common_MiniaturizeH"]]; + [newButton setAction: @selector(miniaturize:)]; + break; + + case NSWindowZoomButton: + // FIXME + newButton = [[RikWindowButton alloc] init]; + [newButton setBaseColor: [NSColor colorWithCalibratedRed: 0.322 green: 0.778 blue: 0.244 alpha: 1]]; + [newButton setAction: @selector(zoom:)]; + break; + + case NSWindowToolbarButton: + // FIXME + newButton = [[NSButton alloc] init]; + [newButton setAction: @selector(toggleToolbarShown:)]; + break; + case NSWindowDocumentIconButton: + default: + newButton = [[NSButton alloc] init]; + // FIXME + break; + } + + [newButton setRefusesFirstResponder: YES]; + [newButton setButtonType: NSMomentaryChangeButton]; + [newButton setImagePosition: NSImageOnly]; + [newButton setBordered: YES]; + [newButton setTag: button]; + return AUTORELEASE(newButton); +} +@end diff --git a/RikWindowButton.h b/RikWindowButton.h new file mode 100644 index 0000000..a438da0 --- /dev/null +++ b/RikWindowButton.h @@ -0,0 +1,14 @@ +#import + + + +@interface RikWindowButton : NSButton +{ +} + +- (void) setBaseColor: (NSColor*)c; ++ (void) initialize;; + + +@end + diff --git a/RikWindowButton.m b/RikWindowButton.m new file mode 100644 index 0000000..bb66913 --- /dev/null +++ b/RikWindowButton.m @@ -0,0 +1,23 @@ +#import "RikWindowButton.h" +#import "RikWindowButtonCell.h" + +@implementation RikWindowButton + ++ (void) initialize +{ + if (self == [RikWindowButton class]) + { + [self setVersion: 1]; + [self setCellClass: [RikWindowButtonCell class]]; + } +} +- (void) setBaseColor: (NSColor*)c +{ + [_cell setBaseColor: c]; +} +- (BOOL) isFlipped +{ + return NO; +} + +@end diff --git a/RikWindowButtonCell.h b/RikWindowButtonCell.h new file mode 100644 index 0000000..2bf43fb --- /dev/null +++ b/RikWindowButtonCell.h @@ -0,0 +1,12 @@ +#import + + + +@interface RikWindowButtonCell : NSButtonCell +{ + NSColor * baseColor; +} +- (void) drawBallWithRect: (NSRect)frame; +- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView; +@property (retain) NSColor * baseColor; +@end diff --git a/RikWindowButtonCell.m b/RikWindowButtonCell.m new file mode 100644 index 0000000..ddc728e --- /dev/null +++ b/RikWindowButtonCell.m @@ -0,0 +1,103 @@ +#include +#include "RikWindowButtonCell.h" + +@implementation RikWindowButtonCell + +@synthesize baseColor; + + +- (void) drawBallWithRect: (NSRect)frame{ + frame = NSInsetRect(frame, 0.5, 0.5); + NSColor * bc = baseColor; + float luminosity = 0.5; + if(_cell.is_highlighted) + { + bc = [baseColor shadowWithLevel: 0.2]; + luminosity = 0.3; + } + NSColor* gradientDownColor1 = [bc highlightWithLevel: luminosity]; + NSColor* gradientDownColor2 = [bc colorWithAlphaComponent: 0]; + NSColor* shadowColor1 = [bc shadowWithLevel: 0.5]; + NSColor* shadowColor2 = [bc shadowWithLevel: 0.8]; + NSColor* gradientStrokeColor2 = [shadowColor1 highlightWithLevel: luminosity]; + NSColor* gradientUpColor1 = [bc highlightWithLevel: luminosity+0.2]; + NSColor* gradientUpColor2 = [gradientUpColor1 colorWithAlphaComponent: 0.5]; + NSColor* gradientUpColor3 = [gradientUpColor1 colorWithAlphaComponent: 0]; + NSColor* light1 = [NSColor whiteColor]; + NSColor* light2 = [light1 colorWithAlphaComponent:0]; + + //// Gradient Declarations + NSGradient* gradientUp = [[NSGradient alloc] initWithColorsAndLocations: + gradientUpColor1, 0.1, + gradientUpColor2, 0.3, + gradientUpColor3, 1.0, nil]; + NSGradient* gradientDown = [[NSGradient alloc] initWithColorsAndLocations: + gradientDownColor1, 0.0, + gradientDownColor2, 1.0, nil]; + NSGradient* baseGradient = [[NSGradient alloc] initWithColorsAndLocations: + bc, 0.0, + shadowColor1, 0.80, nil]; + NSGradient* gradientStroke = [[NSGradient alloc] initWithColorsAndLocations: + light1, 0.2, + light2, 1.0, nil]; + NSGradient* gradientStroke2 = [[NSGradient alloc] initWithColorsAndLocations: + shadowColor2, 0.47, + gradientStrokeColor2, 1.0, nil]; + +//paintcode stuff... + NSRect baseCircleGradientStrokeRect = frame; + NSRect baseCircleGradientStrokeRect2 = NSInsetRect(baseCircleGradientStrokeRect, 0.5, 0.5); + frame = NSInsetRect(frame, 1, 1); + + NSRect baseCircleRect = NSMakeRect(NSMinX(frame) + floor(NSWidth(frame) * 0.06667 + 0.5), NSMinY(frame) + floor(NSHeight(frame) * 0.06667 + 0.5), floor(NSWidth(frame) * 0.93333 + 0.5) - floor(NSWidth(frame) * 0.06667 + 0.5), floor(NSHeight(frame) * 0.93333 + 0.5) - floor(NSHeight(frame) * 0.06667 + 0.5)); + NSRect basecircle2Rect = NSMakeRect(NSMinX(frame) + floor(NSWidth(frame) * 0.06667 + 0.5), NSMinY(frame) + floor(NSHeight(frame) * 0.06667 + 0.5), floor(NSWidth(frame) * 0.93333 + 0.5) - floor(NSWidth(frame) * 0.06667 + 0.5), floor(NSHeight(frame) * 0.93333 + 0.5) - floor(NSHeight(frame) * 0.06667 + 0.5)); + + //// BaseCircleGradientStroke Drawing + NSBezierPath* baseCircleGradientStrokePath = [NSBezierPath bezierPathWithOvalInRect: baseCircleGradientStrokeRect]; + [gradientStroke drawInBezierPath: baseCircleGradientStrokePath angle: 90]; + NSBezierPath* baseCircleGradientStrokePath2 = [NSBezierPath bezierPathWithOvalInRect: baseCircleGradientStrokeRect2]; + [gradientStroke2 drawInBezierPath: baseCircleGradientStrokePath2 angle: -90]; + + + //// BaseCircle Drawing + NSBezierPath* baseCirclePath = [NSBezierPath bezierPathWithOvalInRect: baseCircleRect]; + CGFloat baseCircleResizeRatio = MIN(NSWidth(baseCircleRect) / 13, NSHeight(baseCircleRect) / 13); + [NSGraphicsContext saveGraphicsState]; + [baseCirclePath addClip]; + [baseGradient drawFromCenter: NSMakePoint(NSMidX(baseCircleRect) + 0 * baseCircleResizeRatio, NSMidY(baseCircleRect) + 0 * baseCircleResizeRatio) radius: 2.85 * baseCircleResizeRatio + toCenter: NSMakePoint(NSMidX(baseCircleRect) + 0 * baseCircleResizeRatio, NSMidY(baseCircleRect) + 0 * baseCircleResizeRatio) radius: 7.32 * baseCircleResizeRatio + options: NSGradientDrawsBeforeStartingLocation | NSGradientDrawsAfterEndingLocation]; + [NSGraphicsContext restoreGraphicsState]; + + + //// basecircle2 Drawing + NSBezierPath* basecircle2Path = [NSBezierPath bezierPathWithOvalInRect: basecircle2Rect]; + CGFloat basecircle2ResizeRatio = MIN(NSWidth(basecircle2Rect) / 13, NSHeight(basecircle2Rect) / 13); + [NSGraphicsContext saveGraphicsState]; + [basecircle2Path addClip]; + [gradientDown drawFromCenter: NSMakePoint(NSMidX(basecircle2Rect) + -0.98 * basecircle2ResizeRatio, NSMidY(basecircle2Rect) + -6.5 * basecircle2ResizeRatio) radius: 1.54 * basecircle2ResizeRatio + toCenter: NSMakePoint(NSMidX(basecircle2Rect) + -1.86 * basecircle2ResizeRatio, NSMidY(basecircle2Rect) + -8.73 * basecircle2ResizeRatio) radius: 8.65 * basecircle2ResizeRatio + options: NSGradientDrawsBeforeStartingLocation | NSGradientDrawsAfterEndingLocation]; + [NSGraphicsContext restoreGraphicsState]; + + //// halfcircle Drawing + NSBezierPath* halfcirclePath = [NSBezierPath bezierPath]; + [halfcirclePath moveToPoint: NSMakePoint(NSMinX(frame) + 0.93316 * NSWidth(frame), NSMinY(frame) + 0.46157 * NSHeight(frame))]; + [halfcirclePath curveToPoint: NSMakePoint(NSMinX(frame) + 0.78652 * NSWidth(frame), NSMinY(frame) + 0.81548 * NSHeight(frame)) controlPoint1: NSMakePoint(NSMinX(frame) + 0.93316 * NSWidth(frame), NSMinY(frame) + 0.46157 * NSHeight(frame)) controlPoint2: NSMakePoint(NSMinX(frame) + 0.94476 * NSWidth(frame), NSMinY(frame) + 0.66376 * NSHeight(frame))]; + [halfcirclePath curveToPoint: NSMakePoint(NSMinX(frame) + 0.21348 * NSWidth(frame), NSMinY(frame) + 0.81548 * NSHeight(frame)) controlPoint1: NSMakePoint(NSMinX(frame) + 0.62828 * NSWidth(frame), NSMinY(frame) + 0.96721 * NSHeight(frame)) controlPoint2: NSMakePoint(NSMinX(frame) + 0.37172 * NSWidth(frame), NSMinY(frame) + 0.96721 * NSHeight(frame))]; + [halfcirclePath curveToPoint: NSMakePoint(NSMinX(frame) + 0.06684 * NSWidth(frame), NSMinY(frame) + 0.46157 * NSHeight(frame)) controlPoint1: NSMakePoint(NSMinX(frame) + 0.05524 * NSWidth(frame), NSMinY(frame) + 0.66376 * NSHeight(frame)) controlPoint2: NSMakePoint(NSMinX(frame) + 0.06684 * NSWidth(frame), NSMinY(frame) + 0.46157 * NSHeight(frame))]; + [halfcirclePath lineToPoint: NSMakePoint(NSMinX(frame) + 0.93316 * NSWidth(frame), NSMinY(frame) + 0.46157 * NSHeight(frame))]; + [halfcirclePath closePath]; + [halfcirclePath setLineCapStyle: NSRoundLineCapStyle]; + [halfcirclePath setLineJoinStyle: NSRoundLineJoinStyle]; + [gradientUp drawInBezierPath: halfcirclePath angle: -90]; +} +- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView +{ + if (NSIsEmptyRect(cellFrame)) + return; + if(baseColor != nil) + [self drawBallWithRect: cellFrame]; + [self drawInteriorWithFrame: cellFrame inView: controlView]; +} +@end