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

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

Issue 18486007: Fix the misalignment on CrOS of the tab background images (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
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_controller.h" 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
6 6
7 #import <QuartzCore/QuartzCore.h> 7 #import <QuartzCore/QuartzCore.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 #include <limits> 10 #include <limits>
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 [result addRepresentation:bmpImageRep]; 184 [result addRepresentation:bmpImageRep];
185 } 185 }
186 [NSGraphicsContext restoreGraphicsState]; 186 [NSGraphicsContext restoreGraphicsState];
187 187
188 return result.release(); 188 return result.release();
189 } 189 }
190 190
191 // Takes a normal bitmap and a mask image and returns an image the size of the 191 // Takes a normal bitmap and a mask image and returns an image the size of the
192 // mask that has pixels from |image| but alpha information from |mask|. 192 // mask that has pixels from |image| but alpha information from |mask|.
193 NSImage* ApplyMask(NSImage* image, NSImage* mask) { 193 NSImage* ApplyMask(NSImage* image, NSImage* mask) {
194 DCHECK_EQ([image size].width, [mask size].width);
195 DCHECK_EQ([image size].height, [mask size].height);
196
194 return [CreateImageWithSize([mask size], ^(NSSize size) { 197 return [CreateImageWithSize([mask size], ^(NSSize size) {
195 // Skip a few pixels from the top of the tab background gradient, because 198 [image drawAtPoint:NSZeroPoint
196 // the new tab button is not drawn at the very top of the browser window. 199 fromRect:NSMakeRect(0, 0, size.width, size.height)
197 const int kYOffset = 10; 200 operation:NSCompositeCopy
198 CGFloat width = size.width; 201 fraction:1.0];
199 CGFloat height = size.height;
200
201 // In some themes, the tab background image is narrower than the
202 // new tab button, so tile the background image.
203 CGFloat x = 0;
204 // The floor() is to make sure images with odd widths don't draw to the
205 // same pixel twice on retina displays. (Using NSDrawThreePartImage()
206 // caused a startup perf regression, so that cannot be used.)
207 CGFloat tileWidth = floor(std::min(width, [image size].width));
208 while (x < width) {
209 [image drawAtPoint:NSMakePoint(x, 0)
210 fromRect:NSMakeRect(0,
211 [image size].height - height - kYOffset,
212 tileWidth,
213 height)
214 operation:NSCompositeCopy
215 fraction:1.0];
216 x += tileWidth;
217 }
218
219 [mask drawAtPoint:NSZeroPoint 202 [mask drawAtPoint:NSZeroPoint
220 fromRect:NSMakeRect(0, 0, width, height) 203 fromRect:NSMakeRect(0, 0, size.width, size.height)
221 operation:NSCompositeDestinationIn 204 operation:NSCompositeDestinationIn
222 fraction:1.0]; 205 fraction:1.0];
223 }) autorelease]; 206 }) autorelease];
224 } 207 }
225 208
226 // Creates a modified favicon used for the recording case. The mask is used for 209 // Creates a modified favicon used for the recording case. The mask is used for
227 // making part of the favicon transparent. (The part where the recording dot 210 // making part of the favicon transparent. (The part where the recording dot
228 // later is drawn.) 211 // later is drawn.)
229 NSImage* CreateMaskedFaviconForRecording(NSImage* image, 212 NSImage* CreateMaskedFaviconForRecording(NSImage* image,
230 NSImage* mask, 213 NSImage* mask,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 fromRect:NSMakeRect(0, 0, width, height) 251 fromRect:NSMakeRect(0, 0, width, height)
269 operation:NSCompositeCopy 252 operation:NSCompositeCopy
270 fraction:1.0]; 253 fraction:1.0];
271 [overlay drawAtPoint:NSZeroPoint 254 [overlay drawAtPoint:NSZeroPoint
272 fromRect:NSMakeRect(0, 0, width, height) 255 fromRect:NSMakeRect(0, 0, width, height)
273 operation:NSCompositeSourceOver 256 operation:NSCompositeSourceOver
274 fraction:alpha]; 257 fraction:alpha];
275 }) autorelease]; 258 }) autorelease];
276 } 259 }
277 260
261 // Tiles |image| horizontally into a new NSImage of |size|. |y_inset| refers
262 // to the inset from the bottom of the returned image at which |image| should
263 // be painted.
264 NSImage* TileHorizontally(NSImage* image, CGFloat y_inset, NSSize size) {
265 return [CreateImageWithSize(size, ^(NSSize size) {
266 CGFloat width = size.width;
267 CGFloat height = size.height;
268
269 CGFloat x = 0;
270 // The floor() is to make sure images with odd widths and height don't
271 // draw to the same pixel twice on retina displays. (Using
272 // NSDrawThreePartImage() caused a startup perf regression, so that
273 // cannot be used.)
274 CGFloat tileWidth = floor(std::min(width, [image size].width));
275 while (x < width) {
276 [image drawAtPoint:NSMakePoint(x, 0)
277 fromRect:NSMakeRect(0,
278 [image size].height - y_inset,
279 tileWidth,
280 height)
281 operation:NSCompositeCopy
282 fraction:1.0];
283 x += tileWidth;
284 }
285 }) autorelease];
286 }
287
278 } // namespace 288 } // namespace
279 289
280 @interface TabStripController (Private) 290 @interface TabStripController (Private)
281 - (void)addSubviewToPermanentList:(NSView*)aView; 291 - (void)addSubviewToPermanentList:(NSView*)aView;
282 - (void)regenerateSubviewList; 292 - (void)regenerateSubviewList;
283 - (NSInteger)indexForContentsView:(NSView*)view; 293 - (NSInteger)indexForContentsView:(NSView*)view;
284 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents; 294 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents;
285 - (void)updateFaviconForContents:(content::WebContents*)contents 295 - (void)updateFaviconForContents:(content::WebContents*)contents
286 atIndex:(NSInteger)modelIndex; 296 atIndex:(NSInteger)modelIndex;
287 - (void)layoutTabsWithAnimation:(BOOL)animate 297 - (void)layoutTabsWithAnimation:(BOOL)animate
(...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 ThemeService *theme = 2271 ThemeService *theme =
2262 static_cast<ThemeService*>([[tabStripView_ window] themeProvider]); 2272 static_cast<ThemeService*>([[tabStripView_ window] themeProvider]);
2263 if (!theme) 2273 if (!theme)
2264 return; 2274 return;
2265 2275
2266 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 2276 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
2267 NSImage* mask = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_MASK).ToNSImage(); 2277 NSImage* mask = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_MASK).ToNSImage();
2268 NSImage* normal = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON).ToNSImage(); 2278 NSImage* normal = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON).ToNSImage();
2269 NSImage* hover = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_H).ToNSImage(); 2279 NSImage* hover = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_H).ToNSImage();
2270 NSImage* pressed = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_P).ToNSImage(); 2280 NSImage* pressed = rb.GetNativeImageNamed(IDR_NEWTAB_BUTTON_P).ToNSImage();
2281 NSImage* ntp_bg_active = theme->GetNSImageNamed(
Nico 2013/07/17 18:03:04 useCamelCapsInObjCCode
2282 IDR_THEME_TAB_BACKGROUND, true);
2283 NSImage* ntp_bg_active_overlay = theme->GetNSImageNamed(
2284 IDR_THEME_TAB_BACKGROUND_OVERLAY, false);
2271 2285
2272 NSImage* foreground = ApplyMask( 2286 // Compute the y insets so that |ntp_bg_active| lines up vertically with the
2273 theme->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND, true), mask); 2287 // frame and that |ntp_bg_active_overlay| lines up vertically with the the
2288 // tab. The tab strip has not been layed out yet so
2289 // themePatternPhaseForAlignment cannot be used.
2290 int distance_between_tab_strip_and_button = [[self class] defaultTabHeight] -
2291 NSMaxY([newTabButton_ bounds]);
2292 int distance_between_frame_and_button = NSHeight([tabStripView_ bounds]) -
Nico 2013/07/17 18:03:04 Can you move most of this stuff into a different m
pkotwicz 2013/08/15 07:09:59 I now compute this value in NewTabButtonThemeBackg
2293 NSMaxY([newTabButton_ bounds]);
2294 // ImageButtonCell draws the image centered vertically.
2295 int y_offset_in_button = roundf(
2296 (NSHeight([newTabButton_ bounds]) - [mask size].height) / 2);
2297 // The constants below match those used in
2298 // BrowserWindowUtils::themePatternPhaseForAlignment
Nico 2013/07/17 18:03:04 can they be shared somehow instead?
pkotwicz 2013/08/15 07:09:59 These values are now shared thanks to https://code
2299 int y_inset_align_with_tab_strip = distance_between_tab_strip_and_button +
2300 y_offset_in_button + [mask size].height + 2;
2301 int y_inset_align_with_frame = distance_between_frame_and_button +
2302 y_offset_in_button + [mask size].height + 3;
2303
2304 // Create the foreground image by combining the tinted frame image
2305 // (IDR_THEME_TAB_BACKGROUND) and the custom theme provided overlay
2306 // (IDR_THEME_TAB_BACKGROUND_OVERLAY). Tile the images because the images
2307 // are narrower than the new tab button for some themes.
2308 NSImage* unmasked_foreground = TileHorizontally(ntp_bg_active,
2309 y_inset_align_with_frame, [mask size]);
2310 if (ntp_bg_active_overlay) {
2311 NSImage* tiled_overlay = TileHorizontally(ntp_bg_active_overlay,
2312 y_inset_align_with_tab_strip, [mask size]);
2313 unmasked_foreground = Overlay(unmasked_foreground, tiled_overlay, 1.0);
2314 }
2315 NSImage* foreground = ApplyMask(unmasked_foreground, mask);
2274 2316
2275 [[newTabButton_ cell] setImage:Overlay(foreground, normal, 1.0) 2317 [[newTabButton_ cell] setImage:Overlay(foreground, normal, 1.0)
2276 forButtonState:image_button_cell::kDefaultState]; 2318 forButtonState:image_button_cell::kDefaultState];
2277 [[newTabButton_ cell] setImage:Overlay(foreground, hover, 1.0) 2319 [[newTabButton_ cell] setImage:Overlay(foreground, hover, 1.0)
2278 forButtonState:image_button_cell::kHoverState]; 2320 forButtonState:image_button_cell::kHoverState];
2279 [[newTabButton_ cell] setImage:Overlay(foreground, pressed, 1.0) 2321 [[newTabButton_ cell] setImage:Overlay(foreground, pressed, 1.0)
2280 forButtonState:image_button_cell::kPressedState]; 2322 forButtonState:image_button_cell::kPressedState];
2281 2323
2282 // IDR_THEME_TAB_BACKGROUND_INACTIVE is only used with the default theme. 2324 // IDR_THEME_TAB_BACKGROUND_INACTIVE is only used with the default theme.
2283 if (theme->UsingDefaultTheme()) { 2325 if (theme->UsingDefaultTheme()) {
2284 const CGFloat alpha = tabs::kImageNoFocusAlpha; 2326 const CGFloat alpha = tabs::kImageNoFocusAlpha;
2285 NSImage* background = ApplyMask( 2327 NSImage* unmasked_background = TileHorizontally(
2286 theme->GetNSImageNamed(IDR_THEME_TAB_BACKGROUND_INACTIVE, true), mask); 2328 rb.GetNativeImageNamed(IDR_THEME_TAB_BACKGROUND_INACTIVE).ToNSImage(),
2329 y_inset_align_with_tab_strip,
2330 [mask size]);
2331 NSImage* background = ApplyMask(unmasked_background, mask);
2287 [[newTabButton_ cell] setImage:Overlay(background, normal, alpha) 2332 [[newTabButton_ cell] setImage:Overlay(background, normal, alpha)
2288 forButtonState:image_button_cell::kDefaultStateBackground]; 2333 forButtonState:image_button_cell::kDefaultStateBackground];
2289 [[newTabButton_ cell] setImage:Overlay(background, hover, alpha) 2334 [[newTabButton_ cell] setImage:Overlay(background, hover, alpha)
2290 forButtonState:image_button_cell::kHoverStateBackground]; 2335 forButtonState:image_button_cell::kHoverStateBackground];
2291 } else { 2336 } else {
2292 [[newTabButton_ cell] setImage:nil 2337 [[newTabButton_ cell] setImage:nil
2293 forButtonState:image_button_cell::kDefaultStateBackground]; 2338 forButtonState:image_button_cell::kDefaultStateBackground];
2294 [[newTabButton_ cell] setImage:nil 2339 [[newTabButton_ cell] setImage:nil
2295 forButtonState:image_button_cell::kHoverStateBackground]; 2340 forButtonState:image_button_cell::kHoverStateBackground];
2296 } 2341 }
2297 } 2342 }
2298 2343
2299 @end 2344 @end
2300 2345
2301 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { 2346 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) {
2302 // View hierarchy of the contents view: 2347 // View hierarchy of the contents view:
2303 // NSView -- switchView, same for all tabs 2348 // NSView -- switchView, same for all tabs
2304 // +- NSView -- TabContentsController's view 2349 // +- NSView -- TabContentsController's view
2305 // +- TabContentsViewCocoa 2350 // +- TabContentsViewCocoa
2306 // 2351 //
2307 // Changing it? Do not forget to modify 2352 // Changing it? Do not forget to modify
2308 // -[TabStripController swapInTabAtIndex:] too. 2353 // -[TabStripController swapInTabAtIndex:] too.
2309 return [web_contents->GetView()->GetNativeView() superview]; 2354 return [web_contents->GetView()->GetNativeView() superview];
2310 } 2355 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698