| 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; | |
| 255 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 254 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; | 291 gfx::ScopedNSGraphicsContextSaveGState drawBackgroundState(context); |
| 292 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | |
| 293 CGContextRef cgContext = | 292 CGContextRef cgContext = |
| 294 static_cast<CGContextRef>([context graphicsPort]); | 293 static_cast<CGContextRef>([context graphicsPort]); |
| 295 CGContextBeginTransparencyLayer(cgContext, 0); | 294 CGContextBeginTransparencyLayer(cgContext, 0); |
| 296 CGContextSetAlpha(cgContext, 0.5); | 295 CGContextSetAlpha(cgContext, 0.5); |
| 297 [path addClip]; | 296 [path addClip]; |
| 298 [super drawBackgroundWithOpaque:NO]; | 297 [super drawBackgroundWithOpaque:NO]; |
| 299 CGContextEndTransparencyLayer(cgContext); | 298 CGContextEndTransparencyLayer(cgContext); |
| 300 } | 299 } |
| 301 } | 300 } |
| 302 | 301 |
| 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 |
| 303 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; | 351 BOOL active = [[self window] isKeyWindow] || [[self window] isMainWindow]; |
| 304 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; | 352 CGFloat borderAlpha = selected ? (active ? 0.3 : 0.2) : 0.2; |
| 305 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; | 353 NSColor* borderColor = [NSColor colorWithDeviceWhite:0.0 alpha:borderAlpha]; |
| 306 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( | 354 NSColor* highlightColor = themeProvider ? themeProvider->GetNSColor( |
| 307 themeProvider->UsingDefaultTheme() ? | 355 themeProvider->UsingDefaultTheme() ? |
| 308 ThemeService::COLOR_TOOLBAR_BEZEL : | 356 ThemeService::COLOR_TOOLBAR_BEZEL : |
| 309 ThemeService::COLOR_TOOLBAR, true) : nil; | 357 ThemeService::COLOR_TOOLBAR, true) : nil; |
| 310 | 358 |
| 311 { | 359 // Draw the top inner highlight within the tab if using the default theme. |
| 312 gfx::ScopedNSGraphicsContextSaveGState contextSave; | 360 if (themeProvider && themeProvider->UsingDefaultTheme()) { |
| 313 [path addClip]; | 361 NSAffineTransform* highlightTransform = [NSAffineTransform transform]; |
| 314 | 362 [highlightTransform translateXBy:lineWidth yBy:-lineWidth]; |
| 315 // Use the same overlay for the selected state and for hover and alert | 363 if (selected) { |
| 316 // glows; for the selected state, it's fully opaque. | 364 scoped_nsobject<NSBezierPath> highlightPath([path copy]); |
| 317 CGFloat hoverAlpha = [self hoverAlpha]; | 365 [highlightPath transformUsingAffineTransform:highlightTransform]; |
| 318 CGFloat alertAlpha = [self alertAlpha]; | 366 [highlightColor setStroke]; |
| 319 if (selected || hoverAlpha > 0 || alertAlpha > 0) { | 367 [highlightPath setLineWidth:lineWidth]; |
| 320 // Draw the selected background / glow overlay. | 368 [highlightPath stroke]; |
| 321 gfx::ScopedNSGraphicsContextSaveGState drawHoverState; | 369 highlightTransform = [NSAffineTransform transform]; |
| 322 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 370 [highlightTransform translateXBy:-2 * lineWidth yBy:0.0]; |
| 323 CGContextRef cgContext = | 371 [highlightPath transformUsingAffineTransform:highlightTransform]; |
| 324 static_cast<CGContextRef>([context graphicsPort]); | 372 [highlightPath stroke]; |
| 325 CGContextBeginTransparencyLayer(cgContext, 0); | 373 } else { |
| 326 if (!selected) { | 374 NSBezierPath* topHighlightPath = |
| 327 // The alert glow overlay is like the selected state but at most at most | 375 [self topHighlightBezierPathForRect:[self bounds]]; |
| 328 // 80% opaque. The hover glow brings up the overlay's opacity at most | 376 [topHighlightPath transformUsingAffineTransform:highlightTransform]; |
| 329 // 50%. | 377 [highlightColor setStroke]; |
| 330 CGFloat backgroundAlpha = 0.8 * alertAlpha; | 378 [topHighlightPath setLineWidth:lineWidth]; |
| 331 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; | 379 [topHighlightPath stroke]; |
| 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 } | |
| 386 } | 380 } |
| 387 } | 381 } |
| 388 | 382 |
| 383 [context restoreGraphicsState]; |
| 384 |
| 389 // Draw the top stroke. | 385 // Draw the top stroke. |
| 390 { | 386 { |
| 391 gfx::ScopedNSGraphicsContextSaveGState drawBorderState; | 387 gfx::ScopedNSGraphicsContextSaveGState drawBorderState(context); |
| 392 [borderColor set]; | 388 [borderColor set]; |
| 393 [path setLineWidth:lineWidth]; | 389 [path setLineWidth:lineWidth]; |
| 394 [path stroke]; | 390 [path stroke]; |
| 395 } | 391 } |
| 396 | 392 |
| 397 // Mimic the tab strip's bottom border, which consists of a dark border | 393 // Mimic the tab strip's bottom border, which consists of a dark border |
| 398 // and light highlight. | 394 // and light highlight. |
| 399 if (![controller_ active]) { | 395 if (![controller_ active]) { |
| 400 [path addClip]; | 396 [path addClip]; |
| 401 NSRect borderRect = rect; | 397 NSRect borderRect = rect; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), | 647 NSMakePoint(NSMinX(rect) + kInsetMultiplier * NSHeight(rect), |
| 652 NSMaxY(rect)); | 648 NSMaxY(rect)); |
| 653 | 649 |
| 654 NSBezierPath* path = [NSBezierPath bezierPath]; | 650 NSBezierPath* path = [NSBezierPath bezierPath]; |
| 655 [path moveToPoint:topLeft]; | 651 [path moveToPoint:topLeft]; |
| 656 [path lineToPoint:topRight]; | 652 [path lineToPoint:topRight]; |
| 657 return path; | 653 return path; |
| 658 } | 654 } |
| 659 | 655 |
| 660 @end // @implementation TabView(Private) | 656 @end // @implementation TabView(Private) |
| OLD | NEW |