Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 343 lines (253 sloc) 9.211 kb
1fc15ac @uliwitness Added UKWidgetButton: NSView subclass that draws a close box/zoom box/co...
authored
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
Something went wrong with that request. Please try again.