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/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/mac/sdk_forward_declarations.h" | 9 #include "base/mac/sdk_forward_declarations.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 extern NSString* const _Nonnull NSWorkspaceAccessibilityDisplayOptionsDidChangeN
otification; | 75 extern NSString* const _Nonnull NSWorkspaceAccessibilityDisplayOptionsDidChangeN
otification; |
76 | 76 |
77 namespace { | 77 namespace { |
78 | 78 |
79 enum StrokeType { | 79 enum StrokeType { |
80 STROKE_NORMAL, | 80 STROKE_NORMAL, |
81 STROKE_HEAVY, | 81 STROKE_HEAVY, |
82 }; | 82 }; |
83 | 83 |
84 NSImage* imageForResourceID(int resource_id, StrokeType stroke_type) { | 84 NSImage* imageForResourceID(int resource_id, StrokeType stroke_type) { |
85 if (!ui::MaterialDesignController::IsModeMaterial()) { | |
86 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
87 return [rb.GetNativeImageNamed(resource_id).CopyNSImage() autorelease]; | |
88 } | |
89 | |
90 CGFloat imageWidth = resource_id == IDR_TAB_ACTIVE_CENTER ? 1 : 18; | 85 CGFloat imageWidth = resource_id == IDR_TAB_ACTIVE_CENTER ? 1 : 18; |
91 SEL theSelector = 0; | 86 SEL theSelector = 0; |
92 switch (resource_id) { | 87 switch (resource_id) { |
93 case IDR_TAB_ACTIVE_LEFT: | 88 case IDR_TAB_ACTIVE_LEFT: |
94 theSelector = @selector(drawTabLeftEdgeImage); | 89 theSelector = @selector(drawTabLeftEdgeImage); |
95 break; | 90 break; |
96 | 91 |
97 case IDR_TAB_ACTIVE_CENTER: | 92 case IDR_TAB_ACTIVE_CENTER: |
98 theSelector = @selector(drawTabMiddleEdgeImage); | 93 theSelector = @selector(drawTabMiddleEdgeImage); |
99 break; | 94 break; |
(...skipping 29 matching lines...) Expand all Loading... |
129 ui::ThreePartImage& GetMaskImage() { | 124 ui::ThreePartImage& GetMaskImage() { |
130 CR_DEFINE_STATIC_LOCAL( | 125 CR_DEFINE_STATIC_LOCAL( |
131 ui::ThreePartImage, mask, | 126 ui::ThreePartImage, mask, |
132 (imageForResourceID(IDR_TAB_ALPHA_LEFT, STROKE_NORMAL), nullptr, | 127 (imageForResourceID(IDR_TAB_ALPHA_LEFT, STROKE_NORMAL), nullptr, |
133 imageForResourceID(IDR_TAB_ALPHA_RIGHT, STROKE_NORMAL))); | 128 imageForResourceID(IDR_TAB_ALPHA_RIGHT, STROKE_NORMAL))); |
134 | 129 |
135 return mask; | 130 return mask; |
136 } | 131 } |
137 | 132 |
138 ui::ThreePartImage& GetStrokeImage(bool active, StrokeType stroke_type) { | 133 ui::ThreePartImage& GetStrokeImage(bool active, StrokeType stroke_type) { |
139 if (!ui::MaterialDesignController::IsModeMaterial() && !active) { | |
140 CR_DEFINE_STATIC_LOCAL( | |
141 ui::ThreePartImage, inactiveStroke, | |
142 (imageForResourceID(IDR_TAB_INACTIVE_LEFT, STROKE_NORMAL), | |
143 imageForResourceID(IDR_TAB_INACTIVE_CENTER, STROKE_NORMAL), | |
144 imageForResourceID(IDR_TAB_INACTIVE_RIGHT, STROKE_NORMAL))); | |
145 return inactiveStroke; | |
146 } | |
147 CR_DEFINE_STATIC_LOCAL( | 134 CR_DEFINE_STATIC_LOCAL( |
148 ui::ThreePartImage, stroke, | 135 ui::ThreePartImage, stroke, |
149 (imageForResourceID(IDR_TAB_ACTIVE_LEFT, STROKE_NORMAL), | 136 (imageForResourceID(IDR_TAB_ACTIVE_LEFT, STROKE_NORMAL), |
150 imageForResourceID(IDR_TAB_ACTIVE_CENTER, STROKE_NORMAL), | 137 imageForResourceID(IDR_TAB_ACTIVE_CENTER, STROKE_NORMAL), |
151 imageForResourceID(IDR_TAB_ACTIVE_RIGHT, STROKE_NORMAL))); | 138 imageForResourceID(IDR_TAB_ACTIVE_RIGHT, STROKE_NORMAL))); |
152 CR_DEFINE_STATIC_LOCAL( | 139 CR_DEFINE_STATIC_LOCAL( |
153 ui::ThreePartImage, heavyStroke, | 140 ui::ThreePartImage, heavyStroke, |
154 (imageForResourceID(IDR_TAB_ACTIVE_LEFT, STROKE_HEAVY), | 141 (imageForResourceID(IDR_TAB_ACTIVE_LEFT, STROKE_HEAVY), |
155 imageForResourceID(IDR_TAB_ACTIVE_CENTER, STROKE_HEAVY), | 142 imageForResourceID(IDR_TAB_ACTIVE_CENTER, STROKE_HEAVY), |
156 imageForResourceID(IDR_TAB_ACTIVE_RIGHT, STROKE_HEAVY))); | 143 imageForResourceID(IDR_TAB_ACTIVE_RIGHT, STROKE_HEAVY))); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 closeButton_ = closeButton; | 182 closeButton_ = closeButton; |
196 | 183 |
197 // Make a text field for the title, but don't add it as a subview. | 184 // Make a text field for the title, but don't add it as a subview. |
198 // We will use the cell to draw the text directly into our layer, | 185 // We will use the cell to draw the text directly into our layer, |
199 // so that we can get font smoothing enabled. | 186 // so that we can get font smoothing enabled. |
200 titleView_.reset([[NSTextField alloc] init]); | 187 titleView_.reset([[NSTextField alloc] init]); |
201 [titleView_ setAutoresizingMask:NSViewWidthSizable]; | 188 [titleView_ setAutoresizingMask:NSViewWidthSizable]; |
202 base::scoped_nsobject<GTMFadeTruncatingTextFieldCell> labelCell( | 189 base::scoped_nsobject<GTMFadeTruncatingTextFieldCell> labelCell( |
203 [[GTMFadeTruncatingTextFieldCell alloc] initTextCell:@"Label"]); | 190 [[GTMFadeTruncatingTextFieldCell alloc] initTextCell:@"Label"]); |
204 [labelCell setControlSize:NSSmallControlSize]; | 191 [labelCell setControlSize:NSSmallControlSize]; |
205 // Font size is 12, per Material Design spec. | |
206 CGFloat fontSize = 12; | |
207 if (!ui::MaterialDesignController::IsModeMaterial()) { | |
208 fontSize = [NSFont systemFontSizeForControlSize:NSSmallControlSize]; | |
209 } | |
210 [titleView_ setCell:labelCell]; | 192 [titleView_ setCell:labelCell]; |
211 titleViewCell_ = labelCell; | 193 titleViewCell_ = labelCell; |
212 | 194 |
213 [self setWantsLayer:YES]; // -drawFill: needs a layer. | 195 [self setWantsLayer:YES]; // -drawFill: needs a layer. |
214 | 196 |
215 if (&NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) { | 197 if (&NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) { |
216 NSNotificationCenter* center = | 198 NSNotificationCenter* center = |
217 [[NSWorkspace sharedWorkspace] notificationCenter]; | 199 [[NSWorkspace sharedWorkspace] notificationCenter]; |
218 [center | 200 [center |
219 addObserver:self | 201 addObserver:self |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 - (void)drawFill:(NSRect)dirtyRect { | 403 - (void)drawFill:(NSRect)dirtyRect { |
422 gfx::ScopedNSGraphicsContextSaveGState scopedGState; | 404 gfx::ScopedNSGraphicsContextSaveGState scopedGState; |
423 NSRect bounds = [self bounds]; | 405 NSRect bounds = [self bounds]; |
424 | 406 |
425 NSRect clippingRect = bounds; | 407 NSRect clippingRect = bounds; |
426 clippingRect.size.height = [TabView maskImageFillHeight]; | 408 clippingRect.size.height = [TabView maskImageFillHeight]; |
427 if (state_ != NSOnState) { | 409 if (state_ != NSOnState) { |
428 // Background tabs should not paint over the tab strip separator, which is | 410 // Background tabs should not paint over the tab strip separator, which is |
429 // two pixels high in both lodpi and hidpi, and one pixel high in MD. | 411 // two pixels high in both lodpi and hidpi, and one pixel high in MD. |
430 CGFloat tabStripSeparatorLineWidth = [self cr_lineWidth]; | 412 CGFloat tabStripSeparatorLineWidth = [self cr_lineWidth]; |
431 if (!ui::MaterialDesignController::IsModeMaterial()) { | |
432 tabStripSeparatorLineWidth *= 2; | |
433 } | |
434 clippingRect.origin.y = tabStripSeparatorLineWidth; | 413 clippingRect.origin.y = tabStripSeparatorLineWidth; |
435 clippingRect.size.height -= tabStripSeparatorLineWidth; | 414 clippingRect.size.height -= tabStripSeparatorLineWidth; |
436 } | 415 } |
437 NSRectClip(clippingRect); | 416 NSRectClip(clippingRect); |
438 | 417 |
439 NSPoint position = [[self window] | 418 NSPoint position = [[self window] |
440 themeImagePositionForAlignment:THEME_IMAGE_ALIGN_WITH_TAB_STRIP]; | 419 themeImagePositionForAlignment:THEME_IMAGE_ALIGN_WITH_TAB_STRIP]; |
441 [[NSGraphicsContext currentContext] cr_setPatternPhase:position forView:self]; | 420 [[NSGraphicsContext currentContext] cr_setPatternPhase:position forView:self]; |
442 | 421 |
443 [[self backgroundColorForSelected:(state_ != NSOffState)] set]; | 422 [[self backgroundColorForSelected:(state_ != NSOffState)] set]; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 // theme machinery will make one if given a frame image. See | 458 // theme machinery will make one if given a frame image. See |
480 // BrowserThemePack::GenerateTabBackgroundImages for details. | 459 // BrowserThemePack::GenerateTabBackgroundImages for details. |
481 const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; | 460 const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; |
482 BOOL hasCustomTheme = themeProvider && | 461 BOOL hasCustomTheme = themeProvider && |
483 (themeProvider->HasCustomImage(IDR_THEME_TAB_BACKGROUND) || | 462 (themeProvider->HasCustomImage(IDR_THEME_TAB_BACKGROUND) || |
484 themeProvider->HasCustomImage(IDR_THEME_FRAME)); | 463 themeProvider->HasCustomImage(IDR_THEME_FRAME)); |
485 // Draw a mouse hover gradient for the default themes. | 464 // Draw a mouse hover gradient for the default themes. |
486 if (hoverAlpha > 0) { | 465 if (hoverAlpha > 0) { |
487 if (themeProvider && !hasCustomTheme) { | 466 if (themeProvider && !hasCustomTheme) { |
488 CGFloat whiteValue = 1; | 467 CGFloat whiteValue = 1; |
489 // In MD Incognito mode, give the glow a darker value. | 468 // In Incognito mode, give the glow a darker value. |
490 if (ui::MaterialDesignController::IsModeMaterial() && themeProvider | 469 if (themeProvider && themeProvider->InIncognitoMode()) { |
491 && themeProvider->InIncognitoMode()) { | |
492 whiteValue = 0.5; | 470 whiteValue = 0.5; |
493 } | 471 } |
494 base::scoped_nsobject<NSGradient> glow([NSGradient alloc]); | 472 base::scoped_nsobject<NSGradient> glow([NSGradient alloc]); |
495 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:whiteValue | 473 [glow initWithStartingColor:[NSColor colorWithCalibratedWhite:whiteValue |
496 alpha:1.0 * hoverAlpha] | 474 alpha:1.0 * hoverAlpha] |
497 endingColor:[NSColor colorWithCalibratedWhite:whiteValue | 475 endingColor:[NSColor colorWithCalibratedWhite:whiteValue |
498 alpha:0.0]]; | 476 alpha:0.0]]; |
499 NSRect rect = [self bounds]; | 477 NSRect rect = [self bounds]; |
500 NSPoint point = hoverPoint_; | 478 NSPoint point = hoverPoint_; |
501 point.y = NSHeight(rect); | 479 point.y = NSHeight(rect); |
502 [glow drawFromCenter:point | 480 [glow drawFromCenter:point |
503 radius:0.0 | 481 radius:0.0 |
504 toCenter:point | 482 toCenter:point |
505 radius:NSWidth(rect) / 3.0 | 483 radius:NSWidth(rect) / 3.0 |
506 options:NSGradientDrawsBeforeStartingLocation]; | 484 options:NSGradientDrawsBeforeStartingLocation]; |
507 } | 485 } |
508 } | 486 } |
509 | 487 |
510 CGContextEndTransparencyLayer(cgContext); | 488 CGContextEndTransparencyLayer(cgContext); |
511 } | 489 } |
512 } | 490 } |
513 | 491 |
514 // Draws the tab outline. | 492 // Draws the tab outline. |
515 - (void)drawStroke:(NSRect)dirtyRect { | 493 - (void)drawStroke:(NSRect)dirtyRect { |
516 CGFloat alpha = [[self window] isMainWindow] ? 1.0 : tabs::kImageNoFocusAlpha; | 494 // In MD, the tab stroke is always opaque. |
| 495 CGFloat alpha = 1; |
517 NSRect bounds = [self bounds]; | 496 NSRect bounds = [self bounds]; |
518 if (ui::MaterialDesignController::IsModeMaterial()) { | 497 // In Material Design the tab strip separator is always 1 pixel high - |
519 // In Material Design the tab strip separator is always 1 pixel high - | 498 // add a clip rect to avoid drawing the tab edge over it. |
520 // add a clip rect to avoid drawing the tab edge over it. | 499 NSRect clipRect = bounds; |
521 NSRect clipRect = bounds; | 500 clipRect.origin.y += [self cr_lineWidth]; |
522 clipRect.origin.y += [self cr_lineWidth]; | 501 NSRectClip(clipRect); |
523 NSRectClip(clipRect); | |
524 // In MD, the tab stroke is always opaque. | |
525 alpha = 1; | |
526 } | |
527 const ui::ThemeProvider* provider = [[self window] themeProvider]; | 502 const ui::ThemeProvider* provider = [[self window] themeProvider]; |
528 GetStrokeImage(state_ == NSOnState, | 503 GetStrokeImage(state_ == NSOnState, |
529 provider && provider->ShouldIncreaseContrast() | 504 provider && provider->ShouldIncreaseContrast() |
530 ? STROKE_HEAVY | 505 ? STROKE_HEAVY |
531 : STROKE_NORMAL) | 506 : STROKE_NORMAL) |
532 .DrawInRect(bounds, NSCompositeSourceOver, alpha); | 507 .DrawInRect(bounds, NSCompositeSourceOver, alpha); |
533 } | 508 } |
534 | 509 |
535 - (void)drawRect:(NSRect)dirtyRect { | 510 - (void)drawRect:(NSRect)dirtyRect { |
536 [self drawFill:dirtyRect]; | 511 [self drawFill:dirtyRect]; |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 | 1002 |
1028 // For "Increase Contrast" mode, use flat black instead of semitransparent black | 1003 // For "Increase Contrast" mode, use flat black instead of semitransparent black |
1029 // for the tab edge stroke. | 1004 // for the tab edge stroke. |
1030 + (void)setTabEdgeStrokeColor { | 1005 + (void)setTabEdgeStrokeColor { |
1031 static NSColor* heavyStrokeColor = | 1006 static NSColor* heavyStrokeColor = |
1032 [skia::SkColorToSRGBNSColor(SK_ColorBLACK) retain]; | 1007 [skia::SkColorToSRGBNSColor(SK_ColorBLACK) retain]; |
1033 [heavyStrokeColor set]; | 1008 [heavyStrokeColor set]; |
1034 } | 1009 } |
1035 | 1010 |
1036 @end | 1011 @end |
OLD | NEW |