Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: chrome/browser/ui/cocoa/tabs/tab_strip_background_view.mm

Issue 2430493002: [Mac] Fix rough-looking profile picker text, especially with a dark theme. (Closed)
Patch Set: Scopify! Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_background_view.h" 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h"
6 6
7 #include "chrome/browser/themes/theme_properties.h"
7 #import "chrome/browser/ui/cocoa/framed_browser_window.h" 8 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
8 #import "ui/base/cocoa/nsview_additions.h" 9 #import "ui/base/cocoa/nsview_additions.h"
10 #include "ui/base/theme_provider.h"
9 11
10 @implementation TabStripBackgroundView 12 // TODO(sdy): Remove once we no longer support 10.9 (-Wunguarded-availability).
13 @class NSVisualEffectView;
14 extern NSString* const NSAppearanceNameVibrantDark;
15 extern NSString* const NSAppearanceNameVibrantLight;
16
17 @interface NSAppearance (AllowsVibrancy)
18 @property(readonly) BOOL allowsVibrancy;
19 @end
20 // /TODO
21
22 @interface TabStripThemeBackgroundView : NSView
23 @property(nonatomic) BOOL inATabDraggingOverlayWindow;
24 @end
25
26 @implementation TabStripThemeBackgroundView
27
28 @synthesize inATabDraggingOverlayWindow = inATabDraggingOverlayWindow_;
11 29
12 - (void)drawRect:(NSRect)dirtyRect { 30 - (void)drawRect:(NSRect)dirtyRect {
13 // Only the top corners are rounded. For simplicity, round all 4 corners but 31 // Only the top corners are rounded. For simplicity, round all 4 corners but
14 // draw the bottom corners outside of the visible bounds. 32 // draw the bottom corners outside of the visible bounds.
15 float cornerRadius = 4.0; 33 float cornerRadius = 4.0;
34 bool isFullscreen = (self.window.styleMask & NSFullScreenWindowMask) != 0;
35
16 NSRect roundedRect = [self bounds]; 36 NSRect roundedRect = [self bounds];
17 roundedRect.origin.y -= cornerRadius; 37 if (!isFullscreen) {
18 roundedRect.size.height += cornerRadius; 38 roundedRect.origin.y -= cornerRadius;
19 [[NSBezierPath bezierPathWithRoundedRect:roundedRect 39 roundedRect.size.height += cornerRadius;
20 xRadius:cornerRadius 40 [[NSBezierPath bezierPathWithRoundedRect:roundedRect
21 yRadius:cornerRadius] addClip]; 41 xRadius:cornerRadius
42 yRadius:cornerRadius] addClip];
43 }
22 BOOL themed = [FramedBrowserWindow drawWindowThemeInDirtyRect:dirtyRect 44 BOOL themed = [FramedBrowserWindow drawWindowThemeInDirtyRect:dirtyRect
23 forView:self 45 forView:self
24 bounds:roundedRect 46 bounds:roundedRect
25 forceBlackBackground:NO]; 47 forceBlackBackground:NO];
26 48
27 // Draw a 1px border on the top edge and top corners. 49 // Draw a 1px border on the top edge and top corners.
28 if (themed) { 50 if (themed) {
29 CGFloat lineWidth = [self cr_lineWidth]; 51 if (!isFullscreen) {
30 // Inset the vertical lines by 0.5px so that the top line gets a full pixel. 52 CGFloat lineWidth = [self cr_lineWidth];
31 // Outset the horizontal lines by 0.5px so that they are not visible, but 53 // Inset the vertical lines by 0.5px so that the top line gets a full
32 // still get the rounded corners to get a border. 54 // pixel. Outset the horizontal lines by 0.5px so that they are not
33 NSRect strokeRect = NSInsetRect(roundedRect, -lineWidth/2, lineWidth/2); 55 // visible, but still get the rounded corners to get a border.
34 NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:strokeRect 56 NSRect strokeRect =
35 xRadius:cornerRadius 57 NSInsetRect(roundedRect, -lineWidth / 2, lineWidth / 2);
36 yRadius:cornerRadius]; 58 NSBezierPath* path =
37 [path setLineWidth:lineWidth]; 59 [NSBezierPath bezierPathWithRoundedRect:strokeRect
38 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.5] set]; 60 xRadius:cornerRadius
39 [path stroke]; 61 yRadius:cornerRadius];
62 [path setLineWidth:lineWidth];
63 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.5] set];
64 [path stroke];
65 }
66 } else if (!inATabDraggingOverlayWindow_) {
67 // If the window is not themed, and not being used to drag tabs between
68 // browser windows, decrease the tab strip background's translucency by
69 // overlaying it with a partially-transparent gray. The gray is somewhat
70 // opaque for Incognito mode, very opaque for non-Incognito mode, and
71 // completely opaque when the window is not active.
72 if (const ui::ThemeProvider* themeProvider =
73 [[self window] themeProvider]) {
74 NSColor* overlayColor = nil;
75 if (self.window.isMainWindow) {
76 NSAppearance* appearance = self.effectiveAppearance;
77 if ([appearance respondsToSelector:@selector(allowsVibrancy)] &&
78 appearance.allowsVibrancy) {
79 overlayColor = themeProvider->GetNSColor(
80 ThemeProperties::COLOR_FRAME_VIBRANCY_OVERLAY);
81 } else if (themeProvider->InIncognitoMode()) {
82 overlayColor = [NSColor colorWithSRGBRed:20 / 255.
83 green:22 / 255.
84 blue:24 / 255.
85 alpha:1];
86 } else {
87 overlayColor =
88 themeProvider->GetNSColor(ThemeProperties::COLOR_FRAME);
89 }
90 } else {
91 overlayColor =
92 themeProvider->GetNSColor(ThemeProperties::COLOR_FRAME_INACTIVE);
93 }
94
95 if (overlayColor) {
96 [overlayColor set];
97 NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
98 }
99 }
40 } 100 }
41 } 101 }
102 @end
103
104 @implementation TabStripBackgroundView {
105 // Weak, owned by its superview.
106 TabStripThemeBackgroundView* themeBackgroundView_;
107
108 // Weak, owned by its superview.
109 NSVisualEffectView* visualEffectView_;
110 }
111
112 - (instancetype)initWithFrame:(NSRect)frame {
113 if ((self = [super initWithFrame:frame])) {
114 themeBackgroundView_ = [[[TabStripThemeBackgroundView alloc]
115 initWithFrame:self.bounds] autorelease];
116 themeBackgroundView_.autoresizingMask =
117 NSViewWidthSizable | NSViewHeightSizable;
118 [self addSubview:themeBackgroundView_];
119 }
120 return self;
121 }
122
123 - (BOOL)inATabDraggingOverlayWindow {
124 return themeBackgroundView_.inATabDraggingOverlayWindow;
125 }
126
127 - (void)setInATabDraggingOverlayWindow:(BOOL)inATabDraggingOverlayWindow {
128 themeBackgroundView_.inATabDraggingOverlayWindow =
129 inATabDraggingOverlayWindow;
130 }
131
132 - (void)updateVisualEffectView {
133 const ui::ThemeProvider* themeProvider = [[self window] themeProvider];
134 const bool isFullscreen =
135 (self.window.styleMask & NSFullScreenWindowMask) != 0;
136
137 // Visual effects cause higher power consumption in full screen.
138 if (!isFullscreen && themeProvider->UsingSystemTheme()) {
139 if (!visualEffectView_) {
140 visualEffectView_ =
141 [[[NSVisualEffectView alloc] initWithFrame:self.bounds] autorelease];
142 if (!visualEffectView_)
143 return;
144
145 visualEffectView_.autoresizingMask =
146 NSViewWidthSizable | NSViewHeightSizable;
147 visualEffectView_.appearance =
148 [NSAppearance appearanceNamed:themeProvider->InIncognitoMode()
149 ? NSAppearanceNameVibrantDark
150 : NSAppearanceNameVibrantLight];
151 [self addSubview:visualEffectView_];
152 [visualEffectView_ addSubview:themeBackgroundView_];
153 }
154 } else {
155 if (visualEffectView_) {
156 [self addSubview:themeBackgroundView_];
157 [visualEffectView_ removeFromSuperview];
158 visualEffectView_ = nil;
159 }
160 }
161 }
162
163 - (void)viewWillMoveToWindow:(NSWindow*)newWindow {
164 // AppKit calls this method when the view's position in the view hierarchy
165 // changes, even if its parent window won't change.
166 if (newWindow == self.window)
167 return;
168 if (self.window)
169 [self.window removeObserver:self forKeyPath:@"styleMask"];
170 if (newWindow)
171 [newWindow addObserver:self forKeyPath:@"styleMask" options:0 context:nil];
172 }
173
174 - (void)observeValueForKeyPath:(NSString*)keyPath
175 ofObject:(id)object
176 change:(NSDictionary*)change
177 context:(void*)context {
178 DCHECK_EQ(object, self.window);
179 DCHECK([keyPath isEqualToString:@"styleMask"]);
180 [self updateVisualEffectView];
181 }
42 182
43 // ThemedWindowDrawing implementation. 183 // ThemedWindowDrawing implementation.
44 184
45 - (void)windowDidChangeTheme { 185 - (void)windowDidChangeTheme {
46 [self setNeedsDisplay:YES]; 186 [self updateVisualEffectView];
187 [themeBackgroundView_ setNeedsDisplay:YES];
47 } 188 }
48 189
49 - (void)windowDidChangeActive { 190 - (void)windowDidChangeActive {
50 [self setNeedsDisplay:YES]; 191 // TODO(sdy): It shouldn't be necessary to update the visual effect view
192 // here, since it only changes when the theme changes), but the window isn't
193 // associated with a themeProvider at init time.
194 [self updateVisualEffectView];
195 [themeBackgroundView_ setNeedsDisplay:YES];
51 } 196 }
52 197
53 @end 198 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698