Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: chrome/browser/cocoa/gradient_button_cell.mm

Issue 181002: Reverting 24700. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "base/scoped_nsobject.h"
6 #include "chrome/browser/cocoa/gradient_button_cell.h" 5 #include "chrome/browser/cocoa/gradient_button_cell.h"
7 #import "third_party/GTM/AppKit/GTMTheme.h" 6 #import "third_party/GTM/AppKit/GTMTheme.h"
8 #import "third_party/GTM/AppKit/GTMNSColor+Luminance.h" 7 #import "base/scoped_nsobject.h"
9 8
10 @interface GradientButtonCell (Private) 9 @interface GradientButtonCell (Private)
11 - (void)sharedInit; 10 - (void)sharedInit;
12 - (void)drawUnderlayImageWithFrame:(NSRect)cellFrame 11 - (void)drawUnderlayImageWithFrame:(NSRect)cellFrame
13 inView:(NSView*)controlView; 12 inView:(NSView*)controlView;
14 @end 13 @end
15 14
16 static const NSTimeInterval kAnimationShowDuration = 0.2;
17 static const NSTimeInterval kAnimationHideDuration = 0.4;
18 15
19 @implementation GradientButtonCell 16 @implementation GradientButtonCell
20 @synthesize hoverAlpha = hoverAlpha_;
21
22 - (void)adjustHoverValue {
23 NSTimeInterval thisUpdate = [NSDate timeIntervalSinceReferenceDate];
24
25 NSTimeInterval elapsed = thisUpdate - lastHoverUpdate_;
26
27 CGFloat opacity = [self hoverAlpha];
28 if (isMouseInside_) {
29 opacity += elapsed / kAnimationShowDuration;
30 } else {
31 opacity -= elapsed / kAnimationHideDuration;
32 }
33
34 if (!isMouseInside_ && opacity < 0) {
35 opacity = 0;
36 } else if (isMouseInside_ && opacity > 1) {
37 opacity = 1;
38 } else {
39 [self performSelector:_cmd withObject:nil afterDelay:0.02];
40 }
41 lastHoverUpdate_ = thisUpdate;
42 [self setHoverAlpha:opacity];
43
44 [[self controlView] setNeedsDisplay:YES];
45 }
46
47 - (void)setMouseInside:(BOOL)flag animate:(BOOL)animated {
48 isMouseInside_ = flag;
49 if (animated) {
50 lastHoverUpdate_ = [NSDate timeIntervalSinceReferenceDate];
51 [self adjustHoverValue];
52 } else {
53 [NSObject cancelPreviousPerformRequestsWithTarget:self];
54 [self setHoverAlpha:flag ? 1.0 : 0.0];
55 }
56 [[self controlView] setNeedsDisplay:YES];
57 }
58 17
59 // For nib instantiations 18 // For nib instantiations
60 - (id)initWithCoder:(NSCoder*)decoder { 19 - (id)initWithCoder:(NSCoder*)decoder {
61 if ((self = [super initWithCoder:decoder])) { 20 if ((self = [super initWithCoder:decoder])) {
62 [self sharedInit]; 21 [self sharedInit];
63 } 22 }
64 return self; 23 return self;
65 } 24 }
66 25
67 // For programmatic instantiations 26 // For programmatic instantiations
68 - (id)initTextCell:(NSString*)string { 27 - (id)initTextCell:(NSString*)string {
69 if ((self = [super initTextCell:string])) { 28 if ((self = [super initTextCell:string])) {
70 [self sharedInit]; 29 [self sharedInit];
71 } 30 }
72 return self; 31 return self;
73 } 32 }
74 33
75 - (NSGradient *)gradientForHoverAlpha:(CGFloat)hoverAlpha
76 isThemed:(BOOL)themed {
77 CGFloat startAlpha = 0.6 + 0.3 * hoverAlpha;
78 CGFloat endAlpha = 0.333 * hoverAlpha;
79
80 if (themed) {
81 startAlpha = 0.2 + 0.35 * hoverAlpha;
82 endAlpha = 0.333 * hoverAlpha;
83 }
84
85 NSColor* startColor =
86 [NSColor colorWithCalibratedWhite:1.0
87 alpha:startAlpha];
88 NSColor* endColor =
89 [NSColor colorWithCalibratedWhite:1.0 - 0.15 * hoverAlpha
90 alpha:endAlpha];
91 NSGradient *gradient = [[NSGradient alloc] initWithColorsAndLocations:
92 startColor, hoverAlpha * 0.33,
93 endColor, 1.0, nil];
94
95 return [gradient autorelease];
96 }
97
98
99 - (void)sharedInit { 34 - (void)sharedInit {
100 shouldTheme_ = YES; 35 shouldTheme_ = YES;
101 gradient_.reset([[self gradientForHoverAlpha:0.0 isThemed:NO] retain]); 36 NSColor* startColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.666];
37 NSColor* endColor = [NSColor colorWithCalibratedWhite:1.0 alpha:0.333];
38 gradient_.reset([[NSGradient alloc]
39 initWithColorsAndLocations:startColor, 0.33, endColor, 1.0, nil]);
102 } 40 }
103 41
104 - (void)setShouldTheme:(BOOL)shouldTheme { 42 - (void)setShouldTheme:(BOOL)shouldTheme {
105 shouldTheme_ = shouldTheme; 43 shouldTheme_ = shouldTheme;
106 } 44 }
107 45
108 - (NSImage*)underlayImage { 46 - (NSImage*)underlayImage {
109 return underlayImage_; 47 return underlayImage_;
110 } 48 }
111 49
112 - (void)setUnderlayImage:(NSImage*)image { 50 - (void)setUnderlayImage:(NSImage*)image {
113 underlayImage_.reset([image retain]); 51 underlayImage_.reset([image retain]);
114 52
115 [[self controlView] setNeedsDisplay:YES]; 53 [[self controlView] setNeedsDisplay:YES];
116 } 54 }
117 55
118 - (NSBackgroundStyle)interiorBackgroundStyle { 56 - (NSBackgroundStyle)interiorBackgroundStyle {
119 return [self isHighlighted] ? 57 return [self isHighlighted] ?
120 NSBackgroundStyleLowered : NSBackgroundStyleRaised; 58 NSBackgroundStyleLowered : NSBackgroundStyleRaised;
121 } 59 }
122 60
123 - (void)mouseEntered:(NSEvent *)theEvent { 61 - (void)mouseEntered:(NSEvent *)theEvent {
124 [self setMouseInside:YES animate:YES]; 62 isMouseInside_ = YES;
63 [[self controlView] setNeedsDisplay:YES];
125 } 64 }
126 65
127 - (void)mouseExited:(NSEvent *)theEvent { 66 - (void)mouseExited:(NSEvent *)theEvent {
128 [self setMouseInside:NO animate:YES]; 67 isMouseInside_ = NO;
68 [[self controlView] setNeedsDisplay:YES];
129 } 69 }
130 70
131 - (BOOL)isMouseInside { 71 - (BOOL)isMouseInside {
132 return trackingArea_ && isMouseInside_; 72 return trackingArea_ && isMouseInside_;
133 } 73 }
134 74
135 // Since we have our own drawWithFrame:, we need to also have our own 75 // Since we have our own drawWithFrame:, we need to also have our own
136 // logic for determining when the mouse is inside for honoring this 76 // logic for determining when the mouse is inside for honoring this
137 // request. 77 // request.
138 - (void)setShowsBorderOnlyWhileMouseInside:(BOOL)showOnly { 78 - (void)setShowsBorderOnlyWhileMouseInside:(BOOL)showOnly {
(...skipping 16 matching lines...) Expand all
155 trackingArea_.reset(nil); 95 trackingArea_.reset(nil);
156 isMouseInside_ = NO; 96 isMouseInside_ = NO;
157 } 97 }
158 } 98 }
159 } 99 }
160 100
161 - (void)drawBorderAndFillForTheme:(GTMTheme*)theme 101 - (void)drawBorderAndFillForTheme:(GTMTheme*)theme
162 controlView:(NSView*)controlView 102 controlView:(NSView*)controlView
163 outerPath:(NSBezierPath*)outerPath 103 outerPath:(NSBezierPath*)outerPath
164 innerPath:(NSBezierPath*)innerPath 104 innerPath:(NSBezierPath*)innerPath
105 showHighlightGradient:(BOOL)showHighlightGradient
165 showClickedGradient:(BOOL)showClickedGradient 106 showClickedGradient:(BOOL)showClickedGradient
166 showHighlightGradient:(BOOL)showHighlightGradient
167 hoverAlpha:(CGFloat)hoverAlpha
168 active:(BOOL)active 107 active:(BOOL)active
169 cellFrame:(NSRect)cellFrame { 108 cellFrame:(NSRect)cellFrame {
109 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set];
110 [outerPath stroke];
111
170 NSImage* backgroundImage = 112 NSImage* backgroundImage =
171 [theme backgroundImageForStyle:GTMThemeStyleToolBarButton state:YES]; 113 [theme backgroundImageForStyle:GTMThemeStyleToolBarButton state:YES];
172 114
173 if (backgroundImage) { 115 if (backgroundImage) {
174 NSColor* patternColor = [NSColor colorWithPatternImage:backgroundImage]; 116 NSColor* patternColor = [NSColor colorWithPatternImage:backgroundImage];
175 [patternColor set]; 117 [patternColor set];
176 // Set the phase to match window. 118 // Set the phase to match window.
177 NSRect trueRect = [controlView convertRectToBase:cellFrame]; 119 NSRect trueRect = [controlView convertRectToBase:cellFrame];
178 [[NSGraphicsContext currentContext] 120 [[NSGraphicsContext currentContext]
179 setPatternPhase:NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect))]; 121 setPatternPhase:NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect))];
180 [innerPath fill]; 122 [innerPath fill];
181 } else { 123 } else {
182 if (showClickedGradient) { 124 if (showClickedGradient) {
183 NSGradient* gradient = 125 NSGradient* gradient =
184 [theme gradientForStyle:GTMThemeStyleToolBarButtonPressed 126 [theme gradientForStyle:GTMThemeStyleToolBarButtonPressed
185 state:active]; 127 state:active];
186 [gradient drawInBezierPath:innerPath angle:90.0]; 128 [gradient drawInBezierPath:innerPath angle:90.0];
187 } 129 }
188 } 130 }
189 131
190 BOOL isCustomTheme = backgroundImage != nil; 132 if (!showClickedGradient && showHighlightGradient) {
191
192 if (!showClickedGradient && [self isEnabled]) {
193 [NSGraphicsContext saveGraphicsState]; 133 [NSGraphicsContext saveGraphicsState];
194 [innerPath addClip]; 134 [innerPath addClip];
195 135
196 // Draw the inner glow. 136 // Draw the inner glow.
197 if (hoverAlpha > 0) { 137 [innerPath setLineWidth:2];
198 [innerPath setLineWidth:2]; 138 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.9] setStroke];
199 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2 * hoverAlpha] setStroke]; 139 [innerPath stroke];
200 [innerPath stroke]; 140
201 } 141 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.9] setStroke];
142 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2] setFill];
202 143
203 // Draw the top inner highlight. 144 // Draw the top inner highlight.
204 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; 145 NSAffineTransform* highlightTransform = [NSAffineTransform transform];
205 [highlightTransform translateXBy:1 yBy:1]; 146 [highlightTransform translateXBy:1 yBy:1];
206 scoped_nsobject<NSBezierPath> highlightPath([innerPath copy]); 147 scoped_nsobject<NSBezierPath> highlightPath([innerPath copy]);
207 [highlightPath transformUsingAffineTransform:highlightTransform]; 148 [highlightPath transformUsingAffineTransform:highlightTransform];
208 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.2] setStroke]; 149
209 [highlightPath stroke]; 150 [highlightPath stroke];
210 151
211 NSGradient *gradient = nil; 152 [gradient_ drawInBezierPath:innerPath angle:90.0];
212 if (hoverAlpha == 0 && !isCustomTheme) {
213 gradient = gradient_;
214 } else {
215 gradient = [self gradientForHoverAlpha:hoverAlpha isThemed:isCustomTheme];
216 }
217 [gradient drawInBezierPath:innerPath angle:90.0];
218 153
219 [NSGraphicsContext restoreGraphicsState]; 154 [NSGraphicsContext restoreGraphicsState];
220 } 155 }
221 156
222 // Draw the outer stroke
223 NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton 157 NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton
224 state:active]; 158 state:active];
225
226 if (showClickedGradient) {
227 stroke = [NSColor colorWithCalibratedWhite:0.0 alpha:0.3];
228 }
229 [stroke setStroke]; 159 [stroke setStroke];
230 160
231 [innerPath setLineWidth:1]; 161 [innerPath setLineWidth:1];
232 [innerPath stroke]; 162 [innerPath stroke];
233 } 163 }
234 164
165
235 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { 166 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
236 // Constants from Cole. Will kConstant them once the feedback loop 167 // Constants from Cole. Will kConstant them once the feedback loop
237 // is complete. 168 // is complete.
238 NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5); 169 NSRect drawFrame = NSInsetRect(cellFrame, 1.5, 1.5);
239 NSRect innerFrame = NSInsetRect(cellFrame, 2, 1); 170 NSRect innerFrame = NSInsetRect(cellFrame, 2, 2);
240 ButtonType type = [[(NSControl*)controlView cell] tag]; 171 ButtonType type = [[(NSControl*)controlView cell] tag];
241 switch (type) { 172 switch (type) {
242 case kMiddleButtonType: 173 case kMiddleButtonType:
243 drawFrame.size.width += 20; 174 drawFrame.size.width += 20;
244 innerFrame.size.width += 2; 175 innerFrame.size.width += 2;
245 // Fallthrough 176 // Fallthrough
246 case kRightButtonType: 177 case kRightButtonType:
247 drawFrame.origin.x -= 20; 178 drawFrame.origin.x -= 20;
248 innerFrame.origin.x -= 2; 179 innerFrame.origin.x -= 2;
249 // Fallthrough 180 // Fallthrough
(...skipping 24 matching lines...) Expand all
274 // Stroke the borders and appropriate fill gradient. If we're borderless, 205 // Stroke the borders and appropriate fill gradient. If we're borderless,
275 // the only time we want to draw the inner gradient is if we're highlighted. 206 // the only time we want to draw the inner gradient is if we're highlighted.
276 if (([self isBordered] && ![self showsBorderOnlyWhileMouseInside]) || 207 if (([self isBordered] && ![self showsBorderOnlyWhileMouseInside]) ||
277 pressed || 208 pressed ||
278 [self isMouseInside]) { 209 [self isMouseInside]) {
279 210
280 [self drawBorderAndFillForTheme:theme 211 [self drawBorderAndFillForTheme:theme
281 controlView:controlView 212 controlView:controlView
282 outerPath:outerPath 213 outerPath:outerPath
283 innerPath:innerPath 214 innerPath:innerPath
215 showHighlightGradient:YES
284 showClickedGradient:pressed 216 showClickedGradient:pressed
285 showHighlightGradient:[self isHighlighted]
286 hoverAlpha:[self hoverAlpha]
287 active:active 217 active:active
288 cellFrame:cellFrame]; 218 cellFrame:cellFrame];
289 } 219 }
290 220
291 // If this is the left side of a segmented button, draw a slight shadow. 221 // If this is the left side of a segmented button, draw a slight shadow.
292 if (type == kLeftButtonWithShadowType) { 222 if (type == kLeftButtonWithShadowType) {
293 NSRect borderRect, contentRect; 223 NSRect borderRect, contentRect;
294 NSDivideRect(cellFrame, &borderRect, &contentRect, 1.0, NSMaxXEdge); 224 NSDivideRect(cellFrame, &borderRect, &contentRect, 1.0, NSMaxXEdge);
295 NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton 225 NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton
296 state:active]; 226 state:active];
297 [[stroke colorWithAlphaComponent:0.2] set]; 227 [[stroke colorWithAlphaComponent:0.2] set];
298 NSRectFillUsingOperation(NSInsetRect(borderRect, 0, 2), 228 NSRectFillUsingOperation(NSInsetRect(borderRect, 0, 2),
299 NSCompositeSourceOver); 229 NSCompositeSourceOver);
300 innerFrame.size.width -= 1.0; 230 innerFrame.size.width -= 1.0;
301 } 231 }
302 [self drawInteriorWithFrame:innerFrame inView:controlView]; 232 [self drawInteriorWithFrame:innerFrame inView:controlView];
303 } 233 }
304 234
305 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { 235 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
306 GTMTheme* theme = [controlView gtm_theme]; 236 GTMTheme* theme = [controlView gtm_theme];
307 237
308 if (shouldTheme_) { 238 if (shouldTheme_) {
309 BOOL isTemplate = [[self image] isTemplate]; 239 BOOL isTemplate = [[self image] isTemplate];
310 240
311 [NSGraphicsContext saveGraphicsState]; 241 [NSGraphicsContext saveGraphicsState];
312 242
313 CGContextRef context = 243 CGContextRef context =
314 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]); 244 (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);
315 245
316 NSColor* color = [theme iconColorForStyle:GTMThemeStyleToolBarButton
317 state:YES];
318
319 if (isTemplate) { 246 if (isTemplate) {
320 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); 247 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
321 NSColor *shadowColor = [color gtm_legibleTextColor]; 248 [shadow setShadowColor:[NSColor whiteColor]];
322 shadowColor = [shadowColor colorWithAlphaComponent:0.25];
323 [shadow setShadowColor:shadowColor];
324 [shadow setShadowOffset:NSMakeSize(0, -1.0)]; 249 [shadow setShadowOffset:NSMakeSize(0, -1.0)];
325 [shadow setShadowBlurRadius:1.0]; 250 [shadow setShadowBlurRadius:1.0];
326 [shadow set]; 251 [shadow set];
327 } 252 }
328 253
329 [self drawUnderlayImageWithFrame:cellFrame inView:controlView]; 254 [self drawUnderlayImageWithFrame:cellFrame inView:controlView];
330 255
331 CGContextBeginTransparencyLayer(context, 0); 256 CGContextBeginTransparencyLayer(context, 0);
332 NSRect imageRect = NSZeroRect; 257 NSRect imageRect = NSZeroRect;
333 imageRect.size = [[self image] size]; 258 imageRect.size = [[self image] size];
334 NSRect drawRect = [self imageRectForBounds:cellFrame];
335 [[self image] setFlipped:[controlView isFlipped]]; 259 [[self image] setFlipped:[controlView isFlipped]];
336 [[self image] drawInRect:drawRect 260 [[self image] drawInRect:[self imageRectForBounds:cellFrame]
337 fromRect:imageRect 261 fromRect:imageRect
338 operation:NSCompositeSourceOver 262 operation:NSCompositeSourceOver
339 fraction:[self isEnabled] ? 1.0 : 0.5]; 263 fraction:[self isEnabled] ? 1.0 : 0.5];
340 if (isTemplate) { 264 if (isTemplate) {
265 NSColor* color = [theme iconColorForStyle:GTMThemeStyleToolBarButton
266 state:YES];
341 if (color) { 267 if (color) {
342 [color set]; 268 [color set];
343 NSRectFillUsingOperation(cellFrame, NSCompositeSourceAtop); 269 NSRectFillUsingOperation(cellFrame, NSCompositeSourceAtop);
344 } 270 }
345 } 271 }
346 272
347 CGContextEndTransparencyLayer(context); 273 CGContextEndTransparencyLayer(context);
348 [NSGraphicsContext restoreGraphicsState]; 274 [NSGraphicsContext restoreGraphicsState];
349 } else { 275 } else {
350 [self drawUnderlayImageWithFrame:cellFrame inView:controlView]; 276 [self drawUnderlayImageWithFrame:cellFrame inView:controlView];
(...skipping 12 matching lines...) Expand all
363 imageRect.size = [underlayImage_ size]; 289 imageRect.size = [underlayImage_ size];
364 [underlayImage_ setFlipped:[controlView isFlipped]]; 290 [underlayImage_ setFlipped:[controlView isFlipped]];
365 [underlayImage_ drawInRect:[self imageRectForBounds:cellFrame] 291 [underlayImage_ drawInRect:[self imageRectForBounds:cellFrame]
366 fromRect:imageRect 292 fromRect:imageRect
367 operation:NSCompositeSourceOver 293 operation:NSCompositeSourceOver
368 fraction:[self isEnabled] ? 1.0 : 0.5]; 294 fraction:[self isEnabled] ? 1.0 : 0.5];
369 } 295 }
370 } 296 }
371 297
372 @end 298 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/gradient_button_cell.h ('k') | chrome/browser/cocoa/gradient_button_cell_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698