| 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_strip_view.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
| 6 | 6 |
| 7 #include <cmath> // floor | 7 #include <cmath> // floor |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
| 11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
| 12 #include "base/mac/sdk_forward_declarations.h" | 12 #include "base/mac/sdk_forward_declarations.h" |
| 13 #include "chrome/browser/themes/theme_properties.h" | 13 #include "chrome/browser/themes/theme_properties.h" |
| 14 #include "chrome/browser/themes/theme_service.h" | 14 #include "chrome/browser/themes/theme_service.h" |
| 15 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | |
| 16 #import "chrome/browser/ui/cocoa/browser_window_layout.h" | |
| 17 #import "chrome/browser/ui/cocoa/new_tab_button.h" | 15 #import "chrome/browser/ui/cocoa/new_tab_button.h" |
| 18 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 16 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
| 19 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" | 17 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
| 20 #import "chrome/browser/ui/cocoa/view_id_util.h" | 18 #import "chrome/browser/ui/cocoa/view_id_util.h" |
| 21 #include "chrome/grit/generated_resources.h" | 19 #include "chrome/grit/generated_resources.h" |
| 22 #include "chrome/grit/theme_resources.h" | 20 #include "chrome/grit/theme_resources.h" |
| 23 #import "ui/base/cocoa/appkit_utils.h" | 21 #import "ui/base/cocoa/appkit_utils.h" |
| 24 #import "ui/base/cocoa/nsgraphics_context_additions.h" | 22 #import "ui/base/cocoa/nsgraphics_context_additions.h" |
| 25 #import "ui/base/cocoa/nsview_additions.h" | 23 #import "ui/base/cocoa/nsview_additions.h" |
| 26 #include "ui/base/l10n/l10n_util_mac.h" | 24 #include "ui/base/l10n/l10n_util_mac.h" |
| 27 #include "ui/base/material_design/material_design_controller.h" | 25 #include "ui/base/material_design/material_design_controller.h" |
| 28 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 26 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| 29 | 27 |
| 30 @implementation TabStripView | 28 @implementation TabStripView |
| 31 | 29 |
| 30 @synthesize controller = controller_; |
| 32 @synthesize dropArrowShown = dropArrowShown_; | 31 @synthesize dropArrowShown = dropArrowShown_; |
| 33 @synthesize dropArrowPosition = dropArrowPosition_; | 32 @synthesize dropArrowPosition = dropArrowPosition_; |
| 34 @synthesize inATabDraggingOverlayWindow = inATabDraggingOverlayWindow_; | |
| 35 | 33 |
| 36 - (id)initWithFrame:(NSRect)frame { | 34 - (id)initWithFrame:(NSRect)frame { |
| 37 self = [super initWithFrame:frame]; | 35 self = [super initWithFrame:frame]; |
| 38 if (self) { | 36 if (self) { |
| 39 newTabButton_.reset([[NewTabButton alloc] initWithFrame: | 37 newTabButton_.reset([[NewTabButton alloc] initWithFrame: |
| 40 NSMakeRect(295, 0, 40, 27)]); | 38 NSMakeRect(295, 0, 40, 27)]); |
| 41 [newTabButton_ setToolTip:l10n_util::GetNSString(IDS_TOOLTIP_NEW_TAB)]; | 39 [newTabButton_ setToolTip:l10n_util::GetNSString(IDS_TOOLTIP_NEW_TAB)]; |
| 42 | 40 |
| 43 // Set lastMouseUp_ = -1000.0 so that timestamp-lastMouseUp_ is big unless | 41 // Set lastMouseUp_ = -1000.0 so that timestamp-lastMouseUp_ is big unless |
| 44 // lastMouseUp_ has been reset. | 42 // lastMouseUp_ has been reset. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 strokeColor = [strokeColor colorWithAlphaComponent:100]; | 89 strokeColor = [strokeColor colorWithAlphaComponent:100]; |
| 92 [strokeColor set]; | 90 [strokeColor set]; |
| 93 | 91 |
| 94 NSRect borderRect = NSMakeRect(0.0, 0.0, self.bounds.size.width, | 92 NSRect borderRect = NSMakeRect(0.0, 0.0, self.bounds.size.width, |
| 95 [self cr_lineWidth]); | 93 [self cr_lineWidth]); |
| 96 NSRectFillUsingOperation(NSIntersectionRect(dirtyRect, borderRect), | 94 NSRectFillUsingOperation(NSIntersectionRect(dirtyRect, borderRect), |
| 97 NSCompositeSourceOver); | 95 NSCompositeSourceOver); |
| 98 } | 96 } |
| 99 | 97 |
| 100 - (void)drawRect:(NSRect)dirtyRect { | 98 - (void)drawRect:(NSRect)dirtyRect { |
| 101 const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; | |
| 102 bool hasCustomThemeImage = themeProvider && | |
| 103 themeProvider->HasCustomImage(IDR_THEME_FRAME); | |
| 104 BOOL supportsVibrancy = [self visualEffectView] != nil; | |
| 105 BOOL isMainWindow = [[self window] isMainWindow]; | |
| 106 | |
| 107 // If in Material Design mode, decrease the tabstrip background's translucency | |
| 108 // by overlaying it with a partially-transparent gray (but only if not themed, | |
| 109 // and not being used to drag tabs between browser windows). The gray is | |
| 110 // somewhat opaque for Incognito mode, very opaque for non-Incognito mode, and | |
| 111 // completely opaque when the window is not active. | |
| 112 if (themeProvider && !hasCustomThemeImage && !inATabDraggingOverlayWindow_) { | |
| 113 NSColor* theColor = nil; | |
| 114 if (isMainWindow) { | |
| 115 if (supportsVibrancy && | |
| 116 !themeProvider->HasCustomColor(ThemeProperties::COLOR_FRAME)) { | |
| 117 theColor = themeProvider->GetNSColor( | |
| 118 ThemeProperties::COLOR_FRAME_VIBRANCY_OVERLAY); | |
| 119 } else if (!supportsVibrancy && themeProvider->InIncognitoMode()) { | |
| 120 theColor = [NSColor colorWithSRGBRed:20 / 255. | |
| 121 green:22 / 255. | |
| 122 blue:24 / 255. | |
| 123 alpha:1]; | |
| 124 } else { | |
| 125 theColor = themeProvider->GetNSColor(ThemeProperties::COLOR_FRAME); | |
| 126 } | |
| 127 } else { | |
| 128 theColor = themeProvider->GetNSColor( | |
| 129 ThemeProperties::COLOR_FRAME_INACTIVE); | |
| 130 } | |
| 131 | |
| 132 if (theColor) { | |
| 133 [theColor set]; | |
| 134 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 [self drawBottomEdge:dirtyRect]; | 99 [self drawBottomEdge:dirtyRect]; |
| 139 | 100 |
| 140 // Draw drop-indicator arrow (if appropriate). | 101 // Draw drop-indicator arrow (if appropriate). |
| 141 // TODO(viettrungluu): this is all a stop-gap measure. | 102 // TODO(viettrungluu): this is all a stop-gap measure. |
| 142 if ([self dropArrowShown]) { | 103 if ([self dropArrowShown]) { |
| 143 // Programmer art: an arrow parametrized by many knobs. Note that the arrow | 104 // Programmer art: an arrow parametrized by many knobs. Note that the arrow |
| 144 // points downwards (so understand "width" and "height" accordingly). | 105 // points downwards (so understand "width" and "height" accordingly). |
| 145 | 106 |
| 146 // How many (pixels) to inset on the top/bottom. | 107 // How many (pixels) to inset on the top/bottom. |
| 147 const CGFloat kArrowTopInset = 1.5; | 108 const CGFloat kArrowTopInset = 1.5; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 301 } |
| 341 | 302 |
| 342 - (NewTabButton*)getNewTabButton { | 303 - (NewTabButton*)getNewTabButton { |
| 343 return newTabButton_; | 304 return newTabButton_; |
| 344 } | 305 } |
| 345 | 306 |
| 346 - (void)setNewTabButton:(NewTabButton*)button { | 307 - (void)setNewTabButton:(NewTabButton*)button { |
| 347 newTabButton_.reset([button retain]); | 308 newTabButton_.reset([button retain]); |
| 348 } | 309 } |
| 349 | 310 |
| 350 - (NSVisualEffectView*)visualEffectView { | |
| 351 // NSVisualEffectView is only available on OS X 10.10 and higher. | |
| 352 if (!base::mac::IsAtLeastOS10_10()) | |
| 353 return nil; | |
| 354 | |
| 355 NSView* rootView = [[self window] contentView]; | |
| 356 if (!chrome::ShouldUseFullSizeContentView()) { | |
| 357 rootView = [rootView superview]; | |
| 358 } | |
| 359 | |
| 360 Class nsVisualEffectViewClass = NSClassFromString(@"NSVisualEffectView"); | |
| 361 DCHECK(nsVisualEffectViewClass); | |
| 362 for (NSView* view in [rootView subviews]) { | |
| 363 if ([view isKindOfClass:nsVisualEffectViewClass]) { | |
| 364 return base::mac::ObjCCast<NSVisualEffectView>(view); | |
| 365 } | |
| 366 } | |
| 367 return nil; | |
| 368 } | |
| 369 | |
| 370 - (void)setController:(TabStripController*)controller { | |
| 371 controller_ = controller; | |
| 372 // If tearing down the browser window, there's nothing more to do. | |
| 373 if (!controller_) { | |
| 374 return; | |
| 375 } | |
| 376 | |
| 377 // Finish configuring the NSVisualEffectView so that it matches the window's | |
| 378 // theme. | |
| 379 NSVisualEffectView* visualEffectView = [self visualEffectView]; | |
| 380 const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; | |
| 381 if (!visualEffectView || !themeProvider) { | |
| 382 return; | |
| 383 } | |
| 384 | |
| 385 // Themes with custom frame images don't use vibrancy. Otherwise, if Incognito | |
| 386 // use Material Dark. | |
| 387 if (themeProvider->HasCustomImage(IDR_THEME_FRAME) || | |
| 388 themeProvider->HasCustomColor(ThemeProperties::COLOR_FRAME)) { | |
| 389 [visualEffectView setState:NSVisualEffectStateInactive]; | |
| 390 } else if (themeProvider->InIncognitoMode()) { | |
| 391 [visualEffectView setMaterial:NSVisualEffectMaterialDark]; | |
| 392 [visualEffectView setAppearance: | |
| 393 [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]]; | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 // ThemedWindowDrawing implementation. | 311 // ThemedWindowDrawing implementation. |
| 398 | 312 |
| 399 - (void)windowDidChangeTheme { | 313 - (void)windowDidChangeTheme { |
| 400 [self setNeedsDisplay:YES]; | 314 [self setNeedsDisplay:YES]; |
| 401 [self updateVisualEffectState]; | |
| 402 } | 315 } |
| 403 | 316 |
| 404 - (void)windowDidChangeActive { | 317 - (void)windowDidChangeActive { |
| 405 [self setNeedsDisplay:YES]; | 318 [self setNeedsDisplay:YES]; |
| 406 } | 319 } |
| 407 | 320 |
| 408 - (void)setVisualEffectsDisabledForFullscreen:(BOOL)disabled { | |
| 409 visualEffectsDisabledForFullscreen_ = disabled; | |
| 410 [self updateVisualEffectState]; | |
| 411 } | |
| 412 | |
| 413 - (void)updateVisualEffectState { | |
| 414 // Configure the NSVisualEffectView so that it does nothing if the user has | |
| 415 // switched to a custom theme, or uses vibrancy if the user has switched back | |
| 416 // to the default theme. | |
| 417 NSVisualEffectView* visualEffectView = [self visualEffectView]; | |
| 418 const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; | |
| 419 if (!visualEffectView || !themeProvider) { | |
| 420 return; | |
| 421 } | |
| 422 if (visualEffectsDisabledForFullscreen_ || | |
| 423 themeProvider->HasCustomImage(IDR_THEME_FRAME) || | |
| 424 themeProvider->HasCustomColor(ThemeProperties::COLOR_FRAME)) { | |
| 425 [visualEffectView setState:NSVisualEffectStateInactive]; | |
| 426 } else { | |
| 427 [visualEffectView setState:NSVisualEffectStateFollowsWindowActiveState]; | |
| 428 } | |
| 429 } | |
| 430 | |
| 431 @end | 321 @end |
| OLD | NEW |