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/framed_browser_window.h" | 5 #import "chrome/browser/ui/cocoa/framed_browser_window.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
| 9 #include "chrome/browser/profiles/profile_info_util.h" | 9 #include "chrome/browser/profiles/profile_info_util.h" |
| 10 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 10 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 11 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | |
| 11 #import "chrome/browser/ui/cocoa/custom_frame_view.h" | 12 #import "chrome/browser/ui/cocoa/custom_frame_view.h" |
| 12 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 13 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
| 13 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 14 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
| 14 #import "chrome/browser/ui/cocoa/themed_window.h" | 15 #import "chrome/browser/ui/cocoa/themed_window.h" |
| 15 #include "chrome/browser/themes/theme_properties.h" | 16 #include "chrome/browser/themes/theme_properties.h" |
| 16 #include "chrome/browser/themes/theme_service.h" | 17 #include "chrome/browser/themes/theme_service.h" |
| 17 #include "grit/theme_resources.h" | 18 #include "grit/theme_resources.h" |
| 19 #include "ui/base/cocoa/nsgraphics_context_additions.h" | |
| 18 | 20 |
| 19 // Replicate specific 10.7 SDK declarations for building with prior SDKs. | 21 // Replicate specific 10.7 SDK declarations for building with prior SDKs. |
| 20 #if !defined(MAC_OS_X_VERSION_10_7) || \ | 22 #if !defined(MAC_OS_X_VERSION_10_7) || \ |
| 21 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | 23 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 |
| 22 | 24 |
| 23 @interface NSWindow (LionSDKDeclarations) | 25 @interface NSWindow (LionSDKDeclarations) |
| 24 - (void)toggleFullScreen:(id)sender; | 26 - (void)toggleFullScreen:(id)sender; |
| 25 @end | 27 @end |
| 26 | 28 |
| 27 enum { | 29 enum { |
| 28 NSWindowDocumentVersionsButton = 6, | 30 NSWindowDocumentVersionsButton = 6, |
| 29 NSWindowFullScreenButton | 31 NSWindowFullScreenButton |
| 30 }; | 32 }; |
| 31 | 33 |
| 32 #endif // MAC_OS_X_VERSION_10_7 | 34 #endif // MAC_OS_X_VERSION_10_7 |
| 33 | 35 |
| 34 | 36 |
| 35 // Implementer's note: Moving the window controls is tricky. When altering the | 37 // Implementer's note: Moving the window controls is tricky. When altering the |
| 36 // code, ensure that: | 38 // code, ensure that: |
| 37 // - accessibility hit testing works | 39 // - accessibility hit testing works |
| 38 // - the accessibility hierarchy is correct | 40 // - the accessibility hierarchy is correct |
| 39 // - close/min in the background don't bring the window forward | 41 // - close/min in the background don't bring the window forward |
| 40 // - rollover effects work correctly | 42 // - rollover effects work correctly |
| 41 | 43 |
| 42 namespace { | 44 namespace { |
| 43 | 45 |
| 44 const CGFloat kBrowserFrameViewPaintHeight = 60.0; | 46 const CGFloat kBrowserFrameViewPaintHeight = 60.0; |
| 45 const NSPoint kBrowserFrameViewPatternPhaseOffset = { -5, 3 }; | |
| 46 | 47 |
| 47 // Size of the gradient. Empirically determined so that the gradient looks | 48 // Size of the gradient. Empirically determined so that the gradient looks |
| 48 // like what the heuristic does when there are just a few tabs. | 49 // like what the heuristic does when there are just a few tabs. |
| 49 const CGFloat kWindowGradientHeight = 24.0; | 50 const CGFloat kWindowGradientHeight = 24.0; |
| 50 | 51 |
| 51 } | 52 } |
| 52 | 53 |
| 53 @interface FramedBrowserWindow (Private) | 54 @interface FramedBrowserWindow (Private) |
| 54 | 55 |
| 55 - (void)adjustCloseButton:(NSNotification*)notification; | 56 - (void)adjustCloseButton:(NSNotification*)notification; |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 [[NSBezierPath bezierPathWithRoundedRect:windowRect | 355 [[NSBezierPath bezierPathWithRoundedRect:windowRect |
| 355 xRadius:cornerRadius | 356 xRadius:cornerRadius |
| 356 yRadius:cornerRadius] addClip]; | 357 yRadius:cornerRadius] addClip]; |
| 357 [[NSBezierPath bezierPathWithRect:rect] addClip]; | 358 [[NSBezierPath bezierPathWithRect:rect] addClip]; |
| 358 | 359 |
| 359 // Do the theming. | 360 // Do the theming. |
| 360 BOOL themed = [FramedBrowserWindow | 361 BOOL themed = [FramedBrowserWindow |
| 361 drawWindowThemeInDirtyRect:rect | 362 drawWindowThemeInDirtyRect:rect |
| 362 forView:view | 363 forView:view |
| 363 bounds:windowRect | 364 bounds:windowRect |
| 364 offset:NSZeroPoint | |
| 365 forceBlackBackground:NO]; | 365 forceBlackBackground:NO]; |
| 366 | 366 |
| 367 // If the window needs a title and we painted over the title as drawn by the | 367 // If the window needs a title and we painted over the title as drawn by the |
| 368 // default window paint, paint it ourselves. | 368 // default window paint, paint it ourselves. |
| 369 if (themed && [view respondsToSelector:@selector(_titlebarTitleRect)] && | 369 if (themed && [view respondsToSelector:@selector(_titlebarTitleRect)] && |
| 370 [view respondsToSelector:@selector(_drawTitleStringIn:withColor:)] && | 370 [view respondsToSelector:@selector(_drawTitleStringIn:withColor:)] && |
| 371 ![self _isTitleHidden]) { | 371 ![self _isTitleHidden]) { |
| 372 [view _drawTitleStringIn:[view _titlebarTitleRect] | 372 [view _drawTitleStringIn:[view _titlebarTitleRect] |
| 373 withColor:[self titleColor]]; | 373 withColor:[self titleColor]]; |
| 374 } | 374 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 387 xRadius:cornerRadius | 387 xRadius:cornerRadius |
| 388 yRadius:cornerRadius]; | 388 yRadius:cornerRadius]; |
| 389 [path setLineWidth:lineWidth]; | 389 [path setLineWidth:lineWidth]; |
| 390 [path stroke]; | 390 [path stroke]; |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 + (BOOL)drawWindowThemeInDirtyRect:(NSRect)dirtyRect | 394 + (BOOL)drawWindowThemeInDirtyRect:(NSRect)dirtyRect |
| 395 forView:(NSView*)view | 395 forView:(NSView*)view |
| 396 bounds:(NSRect)bounds | 396 bounds:(NSRect)bounds |
| 397 offset:(NSPoint)offset | |
| 398 forceBlackBackground:(BOOL)forceBlackBackground { | 397 forceBlackBackground:(BOOL)forceBlackBackground { |
| 399 ui::ThemeProvider* themeProvider = [[view window] themeProvider]; | 398 ui::ThemeProvider* themeProvider = [[view window] themeProvider]; |
| 400 if (!themeProvider) | 399 if (!themeProvider) |
| 401 return NO; | 400 return NO; |
| 402 | 401 |
| 403 ThemedWindowStyle windowStyle = [[view window] themedWindowStyle]; | 402 ThemedWindowStyle windowStyle = [[view window] themedWindowStyle]; |
| 404 | 403 |
| 405 // Devtools windows don't get themed. | 404 // Devtools windows don't get themed. |
| 406 if (windowStyle & THEMED_DEVTOOLS) | 405 if (windowStyle & THEMED_DEVTOOLS) |
| 407 return NO; | 406 return NO; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 428 | 427 |
| 429 // If no theme image, use a gradient if incognito. | 428 // If no theme image, use a gradient if incognito. |
| 430 NSGradient* gradient = nil; | 429 NSGradient* gradient = nil; |
| 431 if (!themeImageColor && incognito) | 430 if (!themeImageColor && incognito) |
| 432 gradient = themeProvider->GetNSGradient( | 431 gradient = themeProvider->GetNSGradient( |
| 433 active ? ThemeProperties::GRADIENT_FRAME_INCOGNITO : | 432 active ? ThemeProperties::GRADIENT_FRAME_INCOGNITO : |
| 434 ThemeProperties::GRADIENT_FRAME_INCOGNITO_INACTIVE); | 433 ThemeProperties::GRADIENT_FRAME_INCOGNITO_INACTIVE); |
| 435 | 434 |
| 436 BOOL themed = NO; | 435 BOOL themed = NO; |
| 437 if (themeImageColor) { | 436 if (themeImageColor) { |
| 438 // The titlebar/tabstrip header on the mac is slightly smaller than on | |
| 439 // Windows. To keep the window background lined up with the tab and toolbar | |
| 440 // patterns, we have to shift the pattern slightly, rather than simply | |
| 441 // drawing it from the top left corner. The offset below was empirically | |
| 442 // determined in order to line these patterns up. | |
| 443 // | |
| 444 // This will make the themes look slightly different than in Windows/Linux | |
| 445 // because of the differing heights between window top and tab top, but this | |
| 446 // has been approved by UI. | |
| 447 NSView* frameView = [[[view window] contentView] superview]; | |
| 448 NSPoint topLeft = NSMakePoint(NSMinX(bounds), NSMaxY(bounds)); | |
| 449 NSPoint topLeftInFrameCoordinates = | |
| 450 [view convertPoint:topLeft toView:frameView]; | |
| 451 | |
| 452 NSPoint phase = kBrowserFrameViewPatternPhaseOffset; | |
| 453 phase.x += (offset.x + topLeftInFrameCoordinates.x); | |
| 454 phase.y += (offset.y + topLeftInFrameCoordinates.y); | |
| 455 | |
| 456 // Align the phase to physical pixels so resizing the window under HiDPI | |
| 457 // doesn't cause wiggling of the theme. | |
| 458 phase = [frameView convertPointToBase:phase]; | |
| 459 phase.x = floor(phase.x); | |
| 460 phase.y = floor(phase.y); | |
| 461 phase = [frameView convertPointFromBase:phase]; | |
| 462 | |
| 463 // Default to replacing any existing pixels with the theme image, but if | 437 // Default to replacing any existing pixels with the theme image, but if |
| 464 // asked paint black first and blend the theme with black. | 438 // asked paint black first and blend the theme with black. |
| 465 NSCompositingOperation operation = NSCompositeCopy; | 439 NSCompositingOperation operation = NSCompositeCopy; |
| 466 if (forceBlackBackground) { | 440 if (forceBlackBackground) { |
| 467 [[NSColor blackColor] set]; | 441 [[NSColor blackColor] set]; |
| 468 NSRectFill(dirtyRect); | 442 NSRectFill(dirtyRect); |
| 469 operation = NSCompositeSourceOver; | 443 operation = NSCompositeSourceOver; |
| 470 } | 444 } |
| 471 | 445 |
| 472 [[NSGraphicsContext currentContext] setPatternPhase:phase]; | 446 NSPoint position = [[view window] themeImagePositionForAlignment: |
| 447 THEME_IMAGE_ALIGN_WITH_FRAME]; | |
| 448 | |
| 449 // Align the phase to physical pixels so resizing the window under HiDPI | |
| 450 // doesn't cause wiggling of the theme. | |
| 451 NSView* frameView = [[[view window] contentView] superview]; | |
|
pkotwicz
2013/07/21 23:10:29
I assume that we probably want to move the logic b
Nico
2013/07/22 04:18:01
You can run retina mode on regular macs: http://de
pkotwicz
2013/07/22 21:23:30
I did not notice anything wiggling with the toolba
| |
| 452 position = [frameView convertPointToBase:position]; | |
| 453 position.x = floor(position.x); | |
| 454 position.y = floor(position.y); | |
| 455 position = [frameView convertPointFromBase:position]; | |
| 456 [[NSGraphicsContext currentContext] cr_setPatternPhase:position | |
| 457 forView:view]; | |
| 458 | |
| 473 [themeImageColor set]; | 459 [themeImageColor set]; |
| 474 NSRectFillUsingOperation(dirtyRect, operation); | 460 NSRectFillUsingOperation(dirtyRect, operation); |
| 475 themed = YES; | 461 themed = YES; |
| 476 } else if (gradient) { | 462 } else if (gradient) { |
| 477 NSPoint startPoint = NSMakePoint(NSMinX(bounds), NSMaxY(bounds)); | 463 NSPoint startPoint = NSMakePoint(NSMinX(bounds), NSMaxY(bounds)); |
| 478 NSPoint endPoint = startPoint; | 464 NSPoint endPoint = startPoint; |
| 479 endPoint.y -= kBrowserFrameViewPaintHeight; | 465 endPoint.y -= kBrowserFrameViewPaintHeight; |
| 480 [gradient drawFromPoint:startPoint toPoint:endPoint options:0]; | 466 [gradient drawFromPoint:startPoint toPoint:endPoint options:0]; |
| 481 themed = YES; | 467 themed = YES; |
| 482 } | 468 } |
| 483 | 469 |
| 484 // Check to see if we have an overlay image. | 470 // Check to see if we have an overlay image. |
| 485 NSImage* overlayImage = nil; | 471 NSImage* overlayImage = nil; |
| 486 if (themeProvider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && !incognito && | 472 if (themeProvider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && !incognito && |
| 487 !popup) { | 473 !popup) { |
| 488 overlayImage = themeProvider-> | 474 overlayImage = themeProvider-> |
| 489 GetNSImageNamed(active ? IDR_THEME_FRAME_OVERLAY : | 475 GetNSImageNamed(active ? IDR_THEME_FRAME_OVERLAY : |
| 490 IDR_THEME_FRAME_OVERLAY_INACTIVE, | 476 IDR_THEME_FRAME_OVERLAY_INACTIVE, |
| 491 true); | 477 true); |
| 492 } | 478 } |
| 493 | 479 |
| 494 if (overlayImage) { | 480 if (overlayImage) { |
| 495 // Anchor to top-left and don't scale. | 481 // Anchor to top-left and don't scale. |
| 482 NSView* frameView = [[[view window] contentView] superview]; | |
| 483 NSPoint position = [[view window] themeImagePositionForAlignment: | |
| 484 THEME_IMAGE_ALIGN_WITH_FRAME]; | |
| 485 position = [view convertPoint:position fromView:frameView]; | |
| 496 NSSize overlaySize = [overlayImage size]; | 486 NSSize overlaySize = [overlayImage size]; |
| 497 NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height); | 487 NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height); |
| 498 [overlayImage drawAtPoint:NSMakePoint(offset.x, | 488 [overlayImage drawAtPoint:NSMakePoint(position.x, |
| 499 NSHeight(bounds) + offset.y - | 489 position.y - overlaySize.height) |
| 500 overlaySize.height) | |
| 501 fromRect:imageFrame | 490 fromRect:imageFrame |
| 502 operation:NSCompositeSourceOver | 491 operation:NSCompositeSourceOver |
| 503 fraction:1.0]; | 492 fraction:1.0]; |
| 504 } | 493 } |
| 505 | 494 |
| 506 return themed; | 495 return themed; |
| 507 } | 496 } |
| 508 | 497 |
| 509 - (NSColor*)titleColor { | 498 - (NSColor*)titleColor { |
| 510 ui::ThemeProvider* themeProvider = [self themeProvider]; | 499 ui::ThemeProvider* themeProvider = [self themeProvider]; |
| 511 if (!themeProvider) | 500 if (!themeProvider) |
| 512 return [NSColor windowFrameTextColor]; | 501 return [NSColor windowFrameTextColor]; |
| 513 | 502 |
| 514 ThemedWindowStyle windowStyle = [self themedWindowStyle]; | 503 ThemedWindowStyle windowStyle = [self themedWindowStyle]; |
| 515 BOOL incognito = windowStyle & THEMED_INCOGNITO; | 504 BOOL incognito = windowStyle & THEMED_INCOGNITO; |
| 516 | 505 |
| 517 if (incognito) | 506 if (incognito) |
| 518 return [NSColor whiteColor]; | 507 return [NSColor whiteColor]; |
| 519 else | 508 else |
| 520 return [NSColor windowFrameTextColor]; | 509 return [NSColor windowFrameTextColor]; |
| 521 } | 510 } |
| 522 | 511 |
| 523 @end | 512 @end |
| OLD | NEW |