Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added UKWidgetButton: NSView subclass that draws a close box/zoom box…

…/collapse box pushbutton.

- Colors could still use some slight massaging
- Doesn't draw glyphs in mouse-overed buttons yet
  • Loading branch information...
commit 1fc15aca9ffea5d32f05789b6d6094aed3deae47 1 parent 1ba44cc
Uli Kusterer authored

Showing 2 changed files with 406 additions and 0 deletions. Show diff stats Hide diff stats

  1. +64 0 UKWidgetButton.h
  2. +342 0 UKWidgetButton.m
64 UKWidgetButton.h
... ... @@ -0,0 +1,64 @@
  1 +//
  2 +// UKWidgetButton.h
  3 +// UKBorderlessWidgetizedWindow
  4 +//
  5 +// Created by Uli Kusterer on 27.10.09.
  6 +// Copyright 2009 The Void Software. All rights reserved.
  7 +//
  8 +
  9 +// -----------------------------------------------------------------------------
  10 +// Headers:
  11 +// -----------------------------------------------------------------------------
  12 +
  13 +#import <Cocoa/Cocoa.h>
  14 +
  15 +
  16 +@interface UKWidgetButton : NSView
  17 +{
  18 + BOOL mPressed;
  19 + NSColor *mColor;
  20 + id mTarget;
  21 + SEL mAction;
  22 + BOOL mMouseOver;
  23 + NSTrackingArea *mTrackingArea;
  24 +}
  25 +
  26 +@property (retain) NSColor* color;
  27 +@property (retain) id target;
  28 +@property (assign) SEL action;
  29 +
  30 ++(NSColor*) closeButtonColor;
  31 ++(NSColor*) collapseButtonColor;
  32 ++(NSColor*) zoomButtonColor;
  33 ++(NSColor*) inactiveButtonColor;
  34 ++(NSColor*) defaultButtonColor;
  35 +
  36 ++(SEL) defaultAction;
  37 +
  38 +@end
  39 +
  40 +@interface UKCloseWidgetButton : UKWidgetButton
  41 +{
  42 +
  43 +}
  44 +
  45 +@end
  46 +
  47 +
  48 +@interface UKCollapseWidgetButton : UKWidgetButton
  49 +{
  50 +
  51 +}
  52 +
  53 +@end
  54 +
  55 +@interface UKZoomWidgetButton : UKWidgetButton
  56 +{
  57 +
  58 +}
  59 +
  60 +@end
  61 +
  62 +
  63 +NSString* UKWidgetsMouseEnteredNotification;
  64 +NSString* UKWidgetsMouseLeaveNotification;
342 UKWidgetButton.m
... ... @@ -0,0 +1,342 @@
  1 +//
  2 +// UKWidgetButton.m
  3 +// UKBorderlessWidgetizedWindow
  4 +//
  5 +// Created by Uli Kusterer on 27.10.09.
  6 +// Copyright 2009 The Void Software. All rights reserved.
  7 +//
  8 +
  9 +// -----------------------------------------------------------------------------
  10 +// Headers:
  11 +// -----------------------------------------------------------------------------
  12 +
  13 +#import "UKWidgetButton.h"
  14 +#import "NSColor+UKBrightenDarken.h"
  15 +
  16 +
  17 +// -----------------------------------------------------------------------------
  18 +// Constants:
  19 +// -----------------------------------------------------------------------------
  20 +
  21 +#define WIDGET_SIZE 12.5f
  22 +
  23 +NSString* UKWidgetsMouseEnteredNotification = @"UKWidgetsMouseEnteredNotification";
  24 +NSString* UKWidgetsMouseLeaveNotification = @"UKWidgetsMouseLeaveNotification";
  25 +
  26 +@implementation UKWidgetButton
  27 +
  28 +@synthesize color = mColor;
  29 +@synthesize target = mTarget;
  30 +@synthesize action = mAction;
  31 +
  32 +
  33 ++(NSColor*) closeButtonColor
  34 +{
  35 + return [NSColor colorWithCalibratedRed: 0.901 green: 0.348 blue: 0.090 alpha: 1.000];
  36 +}
  37 +
  38 +
  39 ++(NSColor*) collapseButtonColor
  40 +{
  41 + return [NSColor colorWithCalibratedRed: 0.983 green: 0.861 blue: 0.153 alpha: 1.000];
  42 +}
  43 +
  44 +
  45 ++(NSColor*) zoomButtonColor
  46 +{
  47 + return [NSColor colorWithCalibratedRed: 0.584 green: 0.962 blue: 0.152 alpha: 1.000];
  48 +}
  49 +
  50 +
  51 ++(NSColor*) inactiveButtonColor
  52 +{
  53 + return [NSColor colorWithCalibratedWhite: 0.9 alpha: 1.0];
  54 +}
  55 +
  56 +
  57 ++(NSColor*) defaultButtonColor
  58 +{
  59 + return [[NSColor colorWithCalibratedRed: 0.054 green: 0.317 blue: 0.979 alpha: 1.000] retain];
  60 +}
  61 +
  62 +
  63 ++(SEL) defaultAction
  64 +{
  65 + return Nil;
  66 +}
  67 +
  68 +
  69 +-(id) initWithFrame: (NSRect)frame
  70 +{
  71 + if(( self = [super initWithFrame: frame] ))
  72 + {
  73 + mColor = [[[self class] defaultButtonColor] retain]; // Fallback is blue, just cuz it's not yet used anywhere.
  74 + mAction = [[self class] defaultAction];
  75 + }
  76 +
  77 + return self;
  78 +}
  79 +
  80 +
  81 +-(void) dealloc
  82 +{
  83 + [mColor release];
  84 + mColor = nil;
  85 +
  86 + [mTarget release];
  87 + mTarget = nil;
  88 +
  89 + if( mTrackingArea )
  90 + {
  91 + [self removeTrackingArea: mTrackingArea];
  92 + [mTrackingArea release];
  93 + mTrackingArea = nil;
  94 + }
  95 +
  96 + [super dealloc];
  97 +}
  98 +
  99 +
  100 +-(void) viewWillMoveToWindow: (NSWindow *)newWindow
  101 +{
  102 + NSWindow* theWindow = [self window];
  103 + if( theWindow )
  104 + {
  105 + [[NSNotificationCenter defaultCenter] removeObserver: self name: UKWidgetsMouseLeaveNotification object: theWindow];
  106 + [[NSNotificationCenter defaultCenter] removeObserver: self name: UKWidgetsMouseEnteredNotification object: theWindow];
  107 + [[NSNotificationCenter defaultCenter] removeObserver: self name: NSWindowDidBecomeMainNotification object: nil];
  108 + [[NSNotificationCenter defaultCenter] removeObserver: self name: NSWindowDidResignMainNotification object: nil];
  109 + }
  110 +
  111 + [super viewWillMoveToWindow: newWindow];
  112 +}
  113 +
  114 +
  115 +-(void) viewDidMoveToWindow
  116 +{
  117 + [super viewDidMoveToWindow];
  118 +
  119 + NSWindow* theWindow = [self window];
  120 + if( theWindow )
  121 + {
  122 + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(mouseEnterInOtherWidget:) name: UKWidgetsMouseEnteredNotification object: theWindow];
  123 + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(mouseLeaveInOtherWidget:) name: UKWidgetsMouseLeaveNotification object: theWindow];
  124 + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(owningWindowMainnessChanged:) name: NSWindowDidBecomeMainNotification object: nil];
  125 + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(owningWindowMainnessChanged:) name: NSWindowDidResignMainNotification object: nil];
  126 + }
  127 +}
  128 +
  129 +
  130 +-(void) mouseEnterInOtherWidget: (NSNotification*)notif
  131 +{
  132 + mMouseOver = YES;
  133 + [self setNeedsDisplay: YES];
  134 +}
  135 +
  136 +
  137 +-(void) mouseLeaveInOtherWidget: (NSNotification*)notif
  138 +{
  139 + mMouseOver = NO;
  140 + [self setNeedsDisplay: YES];
  141 +}
  142 +
  143 +
  144 +-(void) owningWindowMainnessChanged: (NSNotification*)notif
  145 +{
  146 + [self setNeedsDisplay: YES];
  147 +}
  148 +
  149 +
  150 +-(void) drawWidgetWithLightColor: (NSColor*)lightBlue
  151 + darkColor: (NSColor*)darkBlue borderColor: (NSColor*)borderBlue
  152 + mainWindow: (BOOL)areMain
  153 +{
  154 + NSColor* whitenedBlue = [lightBlue blendedColorWithFraction: 0.6f ofColor: [NSColor whiteColor]];
  155 + NSColor* midBlue = [darkBlue blendedColorWithFraction: 0.5 ofColor: lightBlue];
  156 + NSColor* shadowBlue = [borderBlue darkenColorBy: 0.1];
  157 + NSRect oneWidgetBox = NSMakeRect( 1, 2, WIDGET_SIZE, WIDGET_SIZE );
  158 + NSBezierPath* widgetPath = [NSBezierPath bezierPathWithOvalInRect: oneWidgetBox];
  159 + [widgetPath setLineWidth: 1.0f];
  160 + NSGradient* widgetBaseGradient = [[[NSGradient alloc] initWithColorsAndLocations:
  161 + whitenedBlue, 0.0, lightBlue, 0.5, midBlue, 0.7, darkBlue, 1.0, nil] autorelease];
  162 + NSGradient* widgetHighlightGradient = [[[NSGradient alloc] initWithColorsAndLocations:
  163 + [NSColor whiteColor], 0.0f, midBlue, 1.0f, nil] autorelease];
  164 +
  165 + // Draw outer shadows and highlights:
  166 + [NSGraphicsContext saveGraphicsState];
  167 + NSShadow* edgeHighlight = [[[NSShadow alloc] init] autorelease];
  168 + [edgeHighlight setShadowOffset: NSMakeSize( 0.0f, -1.0f )];
  169 + [edgeHighlight setShadowBlurRadius: 1.5f];
  170 + [edgeHighlight setShadowColor: [NSColor whiteColor]];
  171 + [edgeHighlight set];
  172 + [widgetPath stroke];
  173 + [NSGraphicsContext restoreGraphicsState];
  174 +
  175 + // Draw main sphere gradient:
  176 + [widgetBaseGradient drawInBezierPath: widgetPath relativeCenterPosition: NSMakePoint( 0, -0.6 )];
  177 +
  178 + // Draw outline:
  179 + [borderBlue set];
  180 + [widgetPath setLineWidth: 0.5f];
  181 + [widgetPath stroke];
  182 + [widgetPath setLineWidth: 1.0f];
  183 +
  184 + // Draw little reflection at top of sphere:
  185 + NSRect widgetHighlightBox = oneWidgetBox;
  186 + widgetHighlightBox.size.width /= 3;
  187 + widgetHighlightBox.size.height /= 3;
  188 +
  189 + widgetHighlightBox.origin.x += (oneWidgetBox.size.width -widgetHighlightBox.size.width) /2;
  190 + widgetHighlightBox.origin.y += (oneWidgetBox.size.height /2) +(oneWidgetBox.size.height /2 -widgetHighlightBox.size.height) /2;
  191 + widgetHighlightBox.origin.y += widgetHighlightBox.size.height / 2;
  192 + [NSGraphicsContext saveGraphicsState];
  193 + [widgetPath addClip];
  194 +
  195 + NSBezierPath* widgetHighlightPath = [NSBezierPath bezierPathWithOvalInRect: widgetHighlightBox];
  196 + [widgetHighlightGradient drawInBezierPath: widgetHighlightPath relativeCenterPosition: NSMakePoint( 0, 0.5 )];
  197 + [NSGraphicsContext restoreGraphicsState];
  198 +
  199 + // Draw shadow at top edge:
  200 + NSRect widgetTopHalfBox = oneWidgetBox;
  201 + widgetTopHalfBox.size.height /= 2;
  202 + widgetTopHalfBox.origin.y += widgetTopHalfBox.size.height;
  203 + widgetTopHalfBox = NSOffsetRect( widgetTopHalfBox, 0.0f, 2.0f );
  204 + NSRect edgeShadowBox = NSInsetRect( oneWidgetBox, -0.0, -0.5f );
  205 + NSBezierPath* edgeShadowPath = [NSBezierPath bezierPathWithOvalInRect: edgeShadowBox];
  206 + [NSGraphicsContext saveGraphicsState];
  207 + [NSBezierPath clipRect: NSInsetRect( widgetTopHalfBox, -1.0f, -2.0f )];
  208 + [shadowBlue set];
  209 + [edgeShadowPath stroke];
  210 + [NSGraphicsContext restoreGraphicsState];
  211 +}
  212 +
  213 +
  214 +-(void) drawWidgetWithColor: (NSColor*)theColor mainWindow: (BOOL)areMain
  215 + pressed: (BOOL)pressed
  216 +{
  217 + if( !areMain )
  218 + theColor = [[self class] inactiveButtonColor];
  219 + if( pressed )
  220 + theColor = [theColor darkenColorBy: 0.4];
  221 +
  222 + NSColor* lightColor = [theColor brightenColorBy: 0.6f];
  223 + NSColor* darkColor = [theColor darkenColorBy: areMain ? 0.5 : 0.3];
  224 + NSColor* borderColor = [theColor darkenColorBy: areMain ? 0.5 : 0.3];
  225 +
  226 + [self drawWidgetWithLightColor: lightColor darkColor: darkColor borderColor: borderColor
  227 + mainWindow: areMain];
  228 +}
  229 +
  230 +
  231 +-(void) drawRect: (NSRect)dirtyRect
  232 +{
  233 + BOOL areMain = [[self window] isMainWindow] || mMouseOver;
  234 +
  235 + [self drawWidgetWithColor: mColor mainWindow: areMain pressed: mPressed];
  236 +}
  237 +
  238 +
  239 +- (BOOL)mouseDownCanMoveWindow
  240 +{
  241 + return NO;
  242 +}
  243 +
  244 +- (void)updateTrackingAreas
  245 +{
  246 + if( mTrackingArea )
  247 + {
  248 + [self removeTrackingArea: mTrackingArea];
  249 + [mTrackingArea release];
  250 + mTrackingArea = nil;
  251 + }
  252 + mTrackingArea = [[NSTrackingArea alloc] initWithRect: [self bounds] options: NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect
  253 + owner: self userInfo: nil];
  254 + [self addTrackingArea: mTrackingArea];
  255 +}
  256 +
  257 +
  258 +-(void) mouseDown: (NSEvent*)evt
  259 +{
  260 + mPressed = YES;
  261 + [self setNeedsDisplay: YES];
  262 +}
  263 +
  264 +-(void) mouseUp: (NSEvent*)evt
  265 +{
  266 + if( mTarget && mAction )
  267 + [mTarget performSelector: mAction withObject: self];
  268 + else if( mTarget )
  269 + [self tryToPerform: mAction with: self];
  270 +
  271 + mPressed = NO;
  272 + [self setNeedsDisplay: YES];
  273 +}
  274 +
  275 +
  276 +-(void) mouseEntered: (NSEvent*)evt
  277 +{
  278 + mMouseOver = YES;
  279 + [self setNeedsDisplay: YES];
  280 +
  281 + [[NSNotificationCenter defaultCenter] postNotificationName: UKWidgetsMouseEnteredNotification object: [self window]];
  282 +}
  283 +
  284 +
  285 +-(void) mouseExited: (NSEvent*)evt
  286 +{
  287 + mMouseOver = NO;
  288 + [self setNeedsDisplay: YES];
  289 +
  290 + [[NSNotificationCenter defaultCenter] postNotificationName: UKWidgetsMouseLeaveNotification object: [self window]];
  291 +}
  292 +
  293 +
  294 +@end
  295 +
  296 +
  297 +@implementation UKCloseWidgetButton
  298 +
  299 ++(NSColor*) defaultButtonColor
  300 +{
  301 + return [[self class] closeButtonColor];
  302 +}
  303 +
  304 ++(SEL) defaultAction
  305 +{
  306 + return @selector(performClose:);
  307 +}
  308 +
  309 +@end
  310 +
  311 +
  312 +@implementation UKCollapseWidgetButton
  313 +
  314 ++(NSColor*) defaultButtonColor
  315 +{
  316 + return [[self class] collapseButtonColor];
  317 +}
  318 +
  319 ++(SEL) defaultAction
  320 +{
  321 + return @selector(performMiniaturize:);
  322 +}
  323 +
  324 +@end
  325 +
  326 +
  327 +@implementation UKZoomWidgetButton
  328 +
  329 ++(NSColor*) defaultButtonColor
  330 +{
  331 + return [[self class] zoomButtonColor];
  332 +}
  333 +
  334 ++(SEL) defaultAction
  335 +{
  336 + return @selector(performZoom:);
  337 +}
  338 +
  339 +@end
  340 +
  341 +
  342 +

0 comments on commit 1fc15ac

Please sign in to comment.
Something went wrong with that request. Please try again.