Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/mac/sdk_forward_declarations.h" | 8 #include "base/mac/sdk_forward_declarations.h" |
| 9 #include "chrome/browser/themes/theme_service.h" | 9 #include "chrome/browser/themes/theme_service.h" |
| 10 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 10 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 }; | 294 }; |
| 295 | 295 |
| 296 // Themes don't have an inactive image so only look for one if there's no | 296 // Themes don't have an inactive image so only look for one if there's no |
| 297 // theme. | 297 // theme. |
| 298 bool active = [[self window] isKeyWindow] || [[self window] isMainWindow] || | 298 bool active = [[self window] isKeyWindow] || [[self window] isMainWindow] || |
| 299 !themeProvider->UsingDefaultTheme(); | 299 !themeProvider->UsingDefaultTheme(); |
| 300 return themeProvider->GetNSImageColorNamed( | 300 return themeProvider->GetNSImageColorNamed( |
| 301 bitmapResources[active][selected], true); | 301 bitmapResources[active][selected], true); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Draws the active tab background. | |
| 305 - (void) drawFillForActiveTab:(NSRect)dirtyRect { | |
|
Nico
2013/07/17 18:03:04
no space after (void)
| |
| 306 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | |
| 307 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | |
| 308 NSPoint phase = [[self window] | |
| 309 themePatternPhaseForAlignment: THEME_PATTERN_ALIGN_WITH_TAB_STRIP]; | |
| 310 [context cr_setPatternPhase:phase forView:self]; | |
| 311 | |
| 312 NSColor* backgroundImageColor = [self backgroundColorForSelected:YES]; | |
| 313 [backgroundImageColor set]; | |
| 314 | |
| 315 // Themes can have partially transparent images. NSRectFill() is measurably | |
| 316 // faster though, so call it for the known-safe default theme. | |
| 317 ThemeService* themeProvider = | |
| 318 static_cast<ThemeService*>([[self window] themeProvider]); | |
| 319 if (themeProvider && themeProvider->UsingDefaultTheme()) | |
| 320 NSRectFill(dirtyRect); | |
| 321 else | |
| 322 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | |
| 323 } | |
| 324 | |
| 304 // Draws the tab background. | 325 // Draws the tab background. |
| 305 - (void)drawFill:(NSRect)dirtyRect { | 326 - (void)drawFill:(NSRect)dirtyRect { |
| 306 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 327 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
| 307 NSGraphicsContext* context = [NSGraphicsContext currentContext]; | 328 NSGraphicsContext* context = [NSGraphicsContext currentContext]; |
| 308 CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); | 329 CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]); |
| 309 | 330 |
| 310 ThemeService* themeProvider = | 331 ThemeService* themeProvider = |
| 311 static_cast<ThemeService*>([[self window] themeProvider]); | 332 static_cast<ThemeService*>([[self window] themeProvider]); |
| 312 [context cr_setPatternPhase:[[self window] themePatternPhase] forView:self]; | 333 bool usingDefaultTheme = themeProvider && themeProvider->UsingDefaultTheme(); |
| 313 | |
| 314 | 334 |
| 315 CGImageRef mask([self tabClippingMask]); | 335 CGImageRef mask([self tabClippingMask]); |
| 316 CGRect maskBounds = CGRectMake(0, 0, maskCacheWidth_, kMaskHeight); | 336 CGRect maskBounds = CGRectMake(0, 0, maskCacheWidth_, kMaskHeight); |
| 317 CGContextClipToMask(cgContext, maskBounds, mask); | 337 CGContextClipToMask(cgContext, maskBounds, mask); |
| 318 | 338 |
| 319 bool selected = [self state]; | 339 if ([self state]) { |
| 340 [self drawFillForActiveTab:dirtyRect]; | |
| 341 return; | |
| 342 } | |
| 320 | 343 |
| 321 // Background tabs should not paint over the tab strip separator, which is | 344 // Background tabs should not paint over the tab strip separator, which is |
| 322 // two pixels high in both lodpi and hidpi. | 345 // two pixels high in both lodpi and hidpi. |
| 323 if (!selected && dirtyRect.origin.y < 1) | 346 if (dirtyRect.origin.y < 1) |
| 324 dirtyRect.origin.y = 2 * [self cr_lineWidth]; | 347 dirtyRect.origin.y = 2 * [self cr_lineWidth]; |
| 325 | 348 |
| 326 bool usingDefaultTheme = themeProvider && themeProvider->UsingDefaultTheme(); | 349 // Draw the tinted frame image. |
| 327 NSColor* backgroundImageColor = [self backgroundColorForSelected:selected]; | 350 NSColor* backgroundImageColor = [self backgroundColorForSelected:NO]; |
| 351 NSPoint phase = [[self window] | |
| 352 themePatternPhaseForAlignment: THEME_PATTERN_ALIGN_WITH_FRAME]; | |
| 353 [context cr_setPatternPhase:phase forView:self]; | |
| 354 [backgroundImageColor set]; | |
| 355 // Themes can have partially transparent images. NSRectFill() is measurably | |
| 356 // faster though, so call it for the known-safe default theme. | |
| 357 if (usingDefaultTheme) | |
| 358 NSRectFill(dirtyRect); | |
| 359 else | |
| 360 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | |
| 328 | 361 |
| 329 // Don't draw the window/tab bar background when selected, since the tab | 362 // If the theme is not the default theme, it may provide a custom overlay |
| 330 // background overlay drawn over it (see below) will be fully opaque. | 363 // image. The overlay image is aligned with the top of the tab. |
| 331 if (!selected) { | 364 NSColor* overlayImageColor = nil; |
| 332 [backgroundImageColor set]; | 365 if (themeProvider) { |
| 333 // Themes can have partially transparent images. NSRectFill() is measurably | 366 overlayImageColor = themeProvider->GetNSImageColorNamed( |
| 334 // faster though, so call it for the known-safe default theme. | 367 IDR_THEME_TAB_BACKGROUND_OVERLAY, false); |
| 335 if (usingDefaultTheme) | 368 } |
| 336 NSRectFill(dirtyRect); | 369 if (overlayImageColor) { |
| 337 else | 370 NSPoint phase = [[self window] |
| 338 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | 371 themePatternPhaseForAlignment: THEME_PATTERN_ALIGN_WITH_TAB_STRIP]; |
| 372 [context cr_setPatternPhase:phase forView:self]; | |
| 373 [overlayImageColor set]; | |
| 374 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | |
| 339 } | 375 } |
| 340 | 376 |
| 341 // Use the same overlay for the selected state and for hover and alert | 377 // Draw the glow for hover and the overlay for alerts. |
| 342 // glows; for the selected state, it's fully opaque. | |
| 343 CGFloat hoverAlpha = [self hoverAlpha]; | 378 CGFloat hoverAlpha = [self hoverAlpha]; |
| 344 CGFloat alertAlpha = [self alertAlpha]; | 379 CGFloat alertAlpha = [self alertAlpha]; |
| 345 if (selected || hoverAlpha > 0 || alertAlpha > 0) { | 380 if (hoverAlpha > 0 || alertAlpha > 0) { |
| 346 gfx::ScopedNSGraphicsContextSaveGState contextSave; | 381 gfx::ScopedNSGraphicsContextSaveGState contextSave; |
| 382 CGContextBeginTransparencyLayer(cgContext, 0); | |
| 347 | 383 |
| 348 // Draw the selected background / glow overlay. | 384 // The alert glow overlay is like the selected state but at most at most 80% |
| 349 CGContextBeginTransparencyLayer(cgContext, 0); | 385 // opaque. The hover glow brings up the overlay's opacity at most 50%. |
| 350 if (!selected) { | 386 CGFloat backgroundAlpha = 0.8 * alertAlpha; |
| 351 // The alert glow overlay is like the selected state but at most at most | 387 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; |
| 352 // 80% opaque. The hover glow brings up the overlay's opacity at most | 388 CGContextSetAlpha(cgContext, backgroundAlpha); |
| 353 // 50%. | |
| 354 CGFloat backgroundAlpha = 0.8 * alertAlpha; | |
| 355 backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha; | |
| 356 CGContextSetAlpha(cgContext, backgroundAlpha); | |
| 357 } | |
| 358 | 389 |
| 359 // For background tabs, this branch is taken to draw a highlight. The | 390 [self drawFillForActiveTab:dirtyRect]; |
| 360 // highlight is drawn using the foreground tab bitmap. | |
| 361 if (!selected && themeProvider) | |
| 362 backgroundImageColor = [self backgroundColorForSelected:YES]; | |
| 363 | |
| 364 [backgroundImageColor set]; | |
| 365 // Themes can have partially transparent images. NSRectFill() is measurably | |
| 366 // faster though, so call it for the known-safe default theme. | |
| 367 if (usingDefaultTheme) | |
| 368 NSRectFill(dirtyRect); | |
|
Nico
2013/07/17 18:03:04
This was called for non-selected tabs with alpha >
| |
| 369 else | |
| 370 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | |
| 371 | 391 |
| 372 // ui::ThemeProvider::HasCustomImage is true only if the theme provides the | 392 // ui::ThemeProvider::HasCustomImage is true only if the theme provides the |
| 373 // image. However, even if the theme doesn't provide a tab background, the | 393 // image. However, even if the theme doesn't provide a tab background, the |
| 374 // theme machinery will make one if given a frame image. See | 394 // theme machinery will make one if given a frame image. See |
| 375 // BrowserThemePack::GenerateTabBackgroundImages for details. | 395 // BrowserThemePack::GenerateTabBackgroundImages for details. |
| 376 BOOL hasCustomTheme = themeProvider && | 396 BOOL hasCustomTheme = themeProvider && |
| 377 (themeProvider->HasCustomImage(IDR_THEME_TAB_BACKGROUND) || | 397 (themeProvider->HasCustomImage(IDR_THEME_TAB_BACKGROUND) || |
| 378 themeProvider->HasCustomImage(IDR_THEME_FRAME)); | 398 themeProvider->HasCustomImage(IDR_THEME_FRAME)); |
| 379 // Draw a mouse hover gradient for the default themes. | 399 // Draw a mouse hover gradient for the default themes. |
| 380 if (!selected && hoverAlpha > 0) { | 400 if (hoverAlpha > 0) { |
| 381 if (themeProvider && !hasCustomTheme) { | 401 if (themeProvider && !hasCustomTheme) { |
| 382 base::scoped_nsobject<NSGradient> glow([NSGradient alloc]); | 402 base::scoped_nsobject<NSGradient> glow([NSGradient alloc]); |
| 383 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 | 403 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 384 alpha:1.0 * hoverAlpha] | 404 alpha:1.0 * hoverAlpha] |
| 385 endingColor:[NSColor colorWithCalibratedWhite:1.0 | 405 endingColor:[NSColor colorWithCalibratedWhite:1.0 |
| 386 alpha:0.0]]; | 406 alpha:0.0]]; |
| 387 NSRect rect = [self bounds]; | 407 NSRect rect = [self bounds]; |
| 388 NSPoint point = hoverPoint_; | 408 NSPoint point = hoverPoint_; |
| 389 point.y = NSHeight(rect); | 409 point.y = NSHeight(rect); |
| 390 [glow drawFromCenter:point | 410 [glow drawFromCenter:point |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 CGFloat middleWidth = tabWidth - leftWidth - rightWidth; | 725 CGFloat middleWidth = tabWidth - leftWidth - rightWidth; |
| 706 NSRect middleRect = NSMakeRect(leftWidth, 0, middleWidth, kFillHeight); | 726 NSRect middleRect = NSMakeRect(leftWidth, 0, middleWidth, kFillHeight); |
| 707 [[NSColor whiteColor] setFill]; | 727 [[NSColor whiteColor] setFill]; |
| 708 NSRectFill(middleRect); | 728 NSRectFill(middleRect); |
| 709 | 729 |
| 710 maskCache_.reset(CGBitmapContextCreateImage(maskContext)); | 730 maskCache_.reset(CGBitmapContextCreateImage(maskContext)); |
| 711 return maskCache_; | 731 return maskCache_; |
| 712 } | 732 } |
| 713 | 733 |
| 714 @end // @implementation TabView(Private) | 734 @end // @implementation TabView(Private) |
| OLD | NEW |