OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/ui/cocoa/tabs/tab_view.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "chrome/browser/themes/theme_service.h" | 8 #include "chrome/browser/themes/theme_service.h" |
9 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 9 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 // If the mouse up occurred in our view or over the close button, then | 244 // If the mouse up occurred in our view or over the close button, then |
245 // close. | 245 // close. |
246 if ([self hitTest:upLocation]) | 246 if ([self hitTest:upLocation]) |
247 [controller_ closeTab:self]; | 247 [controller_ closeTab:self]; |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 - (void)drawRect:(NSRect)dirtyRect { | 251 - (void)drawRect:(NSRect)dirtyRect { |
252 const CGFloat lineWidth = [self cr_lineWidth]; | 252 const CGFloat lineWidth = [self cr_lineWidth]; |
253 | 253 |
| 254 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
254 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 255 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
255 gfx::ScopedNSGraphicsContextSaveGState scopedGState(context); | |
256 | 256 |
257 ThemeService* themeProvider = | 257 ThemeService* themeProvider = |
258 static_cast<ThemeService*>([[self window] themeProvider]); | 258 static_cast<ThemeService*>([[self window] themeProvider]); |
259 [context setPatternPhase:[[self window] themePatternPhase]]; | 259 [context setPatternPhase:[[self window] themePatternPhase]]; |
260 | 260 |
261 NSRect rect = [self bounds]; | 261 NSRect rect = [self bounds]; |
262 NSBezierPath* path = [self bezierPathForRect:rect]; | 262 NSBezierPath* path = [self bezierPathForRect:rect]; |
263 | 263 |
264 BOOL selected = [self state]; | 264 BOOL selected = [self state]; |
265 // Don't draw the window/tab bar background when selected, since the tab | 265 // Don't draw the window/tab bar background when selected, since the tab |
(...skipping 15 matching lines...) Expand all Loading... |
281 if (backgroundImageColor) { | 281 if (backgroundImageColor) { |
282 [backgroundImageColor set]; | 282 [backgroundImageColor set]; |
283 [path fill]; | 283 [path fill]; |
284 } else { | 284 } else { |
285 // Use the window's background color rather than |[NSColor | 285 // Use the window's background color rather than |[NSColor |
286 // windowBackgroundColor]|, which gets confused by the fullscreen window. | 286 // windowBackgroundColor]|, which gets confused by the fullscreen window. |
287 // (The result is the same for normal, non-fullscreen windows.) | 287 // (The result is the same for normal, non-fullscreen windows.) |
288 [[[self window] backgroundColor] set]; | 288 [[[self window] backgroundColor] set]; |
289 [path fill]; | 289 [path fill]; |
290 | 290 |
291 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); | 291 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState; |
| 292 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
292 CGContextRef cgContext = | 293 CGContextRef cgContext = |
293 static_cast<CGContextRef>([context graphicsPort]); | 294 static_cast<CGContextRef>([context graphicsPort]); |
294 CGContextBeginTransparencyLayer(cgContext, 0); | 295 CGContextBeginTransparencyLayer(cgContext, 0); |
295 CGContextSetAlpha(cgContext, 0.5); | 296 CGContextSetAlpha(cgContext, 0.5); |
296 [path addClip]; | 297 [path addClip]; |
297 [super drawBackgroundWithOpaque:NO]; | 298 [super drawBackgroundWithOpaque:NO]; |
298 CGContextEndTransparencyLayer(cgContext); | 299 CGContextEndTransparencyLayer(cgContext); |
299 } | 300 } |
300 } | 301 } |
301 | 302 |
302 [context saveGraphicsState]; | |
303 [path addClip]; | |
304 | |
305 // Use the same overlay for the selected state and for hover and alert glows; | |
306 // for the selected state, it's fully opaque. | |
307 CGFloat hoverAlpha = [self hoverAlpha]; | |
308 CGFloat alertAlpha = [self alertAlpha]; | |
309 if (selected || hoverAlpha > 0 || alertAlpha > 0) { | |
310 // Draw the selected background / glow overlay. | |
311 gfx::ScopedNSGraphicsContextSaveGState drawHoverState(context); | |
312 CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); | |
313 CGContextBeginTransparencyLayer(cgContext, 0); | |
314 if (!selected) { | |
315 // The alert glow overlay is like the selected state but at most at most | |
316 // 80% opaque. The hover glow brings up the overlay's opacity at most 50%. | |
317 CGFloat backgroundAlpha = 0.8 * alertAlpha; | |
318 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; | |
319 CGContextSetAlpha(cgContext, backgroundAlpha); | |
320 } | |
321 [path addClip]; | |
322 { | |
323 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); | |
324 [super drawBackgroundWithOpaque:NO]; | |
325 } | |
326 | |
327 // Draw a mouse hover gradient for the default themes. | |
328 if (!selected && hoverAlpha > 0) { | |
329 if (themeProvider && !hasBackgroundImage) { | |
330 scoped_nsobject<NSGradient> glow([NSGradient alloc]); | |
331 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 | |
332 alpha:1.0 * hoverAlpha] | |
333 endingColor:[NSColor colorWithCalibratedWhite:1.0 | |
334 alpha:0.0]]; | |
335 | |
336 NSPoint point = hoverPoint_; | |
337 point.y = NSHeight(rect); | |
338 [glow drawFromCenter:point | |
339 radius:0.0 | |
340 toCenter:point | |
341 radius:NSWidth(rect) / 3.0 | |
342 options:NSGradientDrawsBeforeStartingLocation]; | |
343 | |
344 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; | |
345 } | |
346 } | |
347 | |
348 CGContextEndTransparencyLayer(cgContext); | |
349 } | |
350 | |
351 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; | 303 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; |
352 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; | 304 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; |
353 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; | 305 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; |
354 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( | 306 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( |
355 themeProvider->UsingDefaultTheme() ? | 307 themeProvider->UsingDefaultTheme() ? |
356 ThemeService::COLOR_TOOLBAR_BEZEL : | 308 ThemeService::COLOR_TOOLBAR_BEZEL : |
357 ThemeService::COLOR_TOOLBAR, true) : nil; | 309 ThemeService::COLOR_TOOLBAR, true) : nil; |
358 | 310 |
359 // Draw the top inner highlight within the tab if using the default theme. | 311 { |
360 if (themeProvider && themeProvider->UsingDefaultTheme()) { | 312 gfx::ScopedNSGraphicsContextSaveGState contextSave; |
361 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; | 313 [path addClip]; |
362 [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; | 314 |
363 if (selected) { | 315 // Use the same overlay for the selected state and for hover and alert |
364 scoped_nsobject<NSBezierPath> highlightPath([path copy]); | 316 // glows; for the selected state, it's fully opaque. |
365 [highlightPath transformUsingAffineTransform:highlightTransform]; | 317 CGFloat hoverAlpha = [self hoverAlpha]; |
366 [highlightColor setStroke]; | 318 CGFloat alertAlpha = [self alertAlpha]; |
367 [highlightPath setLineWidth:lineWidth]; | 319 if (selected || hoverAlpha > 0 || alertAlpha > 0) { |
368 [highlightPath stroke]; | 320 // Draw the selected background / glow overlay. |
369 highlightTransform = [NSAffineTransform transform]; | 321 gfx::ScopedNSGraphicsContextSaveGState drawHoverState; |
370 [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; | 322 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
371 [highlightPath transformUsingAffineTransform:highlightTransform]; | 323 CGContextRef cgContext = |
372 [highlightPath stroke]; | 324 static_cast<CGContextRef>([context graphicsPort]); |
373 } else { | 325 CGContextBeginTransparencyLayer(cgContext, 0); |
374 NSBezierPath* topHighlightPath = | 326 if (!selected) { |
375 [self topHighlightBezierPathForRect:[self bounds]]; | 327 // The alert glow overlay is like the selected state but at most at most |
376 [topHighlightPath transformUsingAffineTransform:highlightTransform]; | 328 // 80% opaque. The hover glow brings up the overlay's opacity at most |
377 [highlightColor setStroke]; | 329 // 50%. |
378 [topHighlightPath setLineWidth:lineWidth]; | 330 CGFloat backgroundAlpha = 0.8 * alertAlpha; |
379 [topHighlightPath stroke]; | 331 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; |
| 332 CGContextSetAlpha(cgContext, backgroundAlpha); |
| 333 } |
| 334 [path addClip]; |
| 335 { |
| 336 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState; |
| 337 [super drawBackgroundWithOpaque:NO]; |
| 338 } |
| 339 |
| 340 // Draw a mouse hover gradient for the default themes. |
| 341 if (!selected && hoverAlpha > 0) { |
| 342 if (themeProvider && !hasBackgroundImage) { |
| 343 scoped_nsobject<NSGradient> glow([NSGradient alloc]); |
| 344 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 345 alpha:1.0 * hoverAlpha] |
| 346 endingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 347 alpha:0.0]]; |
| 348 |
| 349 NSPoint point = hoverPoint_; |
| 350 point.y = NSHeight(rect); |
| 351 [glow drawFromCenter:point |
| 352 radius:0.0 |
| 353 toCenter:point |
| 354 radius:NSWidth(rect) / 3.0 |
| 355 options:NSGradientDrawsBeforeStartingLocation]; |
| 356 |
| 357 [glow drawInBezierPath:path relativeCenterPosition:hoverPoint_]; |
| 358 } |
| 359 } |
| 360 |
| 361 CGContextEndTransparencyLayer(cgContext); |
| 362 } |
| 363 |
| 364 // Draw the top inner highlight within the tab if using the default theme. |
| 365 if (themeProvider && themeProvider->UsingDefaultTheme()) { |
| 366 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; |
| 367 [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; |
| 368 if (selected) { |
| 369 scoped_nsobject<NSBezierPath> highlightPath([path copy]); |
| 370 [highlightPath transformUsingAffineTransform:highlightTransform]; |
| 371 [highlightColor setStroke]; |
| 372 [highlightPath setLineWidth:lineWidth]; |
| 373 [highlightPath stroke]; |
| 374 highlightTransform = [NSAffineTransform transform]; |
| 375 [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; |
| 376 [highlightPath transformUsingAffineTransform:highlightTransform]; |
| 377 [highlightPath stroke]; |
| 378 } else { |
| 379 NSBezierPath* topHighlightPath = |
| 380 [self topHighlightBezierPathForRect:[self bounds]]; |
| 381 [topHighlightPath transformUsingAffineTransform:highlightTransform]; |
| 382 [highlightColor setStroke]; |
| 383 [topHighlightPath setLineWidth:lineWidth]; |
| 384 [topHighlightPath stroke]; |
| 385 } |
380 } | 386 } |
381 } | 387 } |
382 | 388 |
383 [context restoreGraphicsState]; | |
384 | |
385 // Draw the top stroke. | 389 // Draw the top stroke. |
386 { | 390 { |
387 gfx::ScopedNSGraphicsContextSaveGState drawBorderState(context); | 391 gfx::ScopedNSGraphicsContextSaveGState drawBorderState; |
388 [borderColor set]; | 392 [borderColor set]; |
389 [path setLineWidth:lineWidth]; | 393 [path setLineWidth:lineWidth]; |
390 [path stroke]; | 394 [path stroke]; |
391 } | 395 } |
392 | 396 |
393 // Mimic the tab strip's bottom border, which consists of a dark border | 397 // Mimic the tab strip's bottom border, which consists of a dark border |
394 // and light highlight. | 398 // and light highlight. |
395 if (![controller_ active]) { | 399 if (![controller_ active]) { |
396 [path addClip]; | 400 [path addClip]; |
397 NSRect borderRect = rect; | 401 NSRect borderRect = rect; |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), | 651 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), |
648 NSMaxY(rect)); | 652 NSMaxY(rect)); |
649 | 653 |
650 NSBezierPath* path = [NSBezierPath bezierPath]; | 654 NSBezierPath* path = [NSBezierPath bezierPath]; |
651 [path moveToPoint:topLeft]; | 655 [path moveToPoint:topLeft]; |
652 [path lineToPoint:topRight]; | 656 [path lineToPoint:topRight]; |
653 return path; | 657 return path; |
654 } | 658 } |
655 | 659 |
656 @end // @implementation TabView(Private) | 660 @end // @implementation TabView(Private) |
OLD | NEW |