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

Side by Side Diff: chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm

Issue 2845003003: [Mac] Reverse bookmark buttons and menus in RTL (take 2) (Closed)
Patch Set: CL comments Created 3 years, 7 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/bookmarks/bookmark_button_cell.h" 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/user_metrics.h" 8 #include "base/metrics/user_metrics.h"
9 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
10 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" 10 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" 11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controlle r.h" 12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controlle r.h"
13 #include "chrome/browser/ui/cocoa/l10n_util.h"
13 #include "chrome/grit/generated_resources.h" 14 #include "chrome/grit/generated_resources.h"
14 #import "components/bookmarks/browser/bookmark_model.h" 15 #import "components/bookmarks/browser/bookmark_model.h"
15 #import "ui/base/cocoa/nsview_additions.h" 16 #import "ui/base/cocoa/nsview_additions.h"
16 #include "ui/base/l10n/l10n_util_mac.h" 17 #include "ui/base/l10n/l10n_util_mac.h"
17 #include "ui/base/material_design/material_design_controller.h" 18 #include "ui/base/material_design/material_design_controller.h"
18 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/resources/grit/ui_resources.h" 20 #include "ui/resources/grit/ui_resources.h"
20 21
21 using base::UserMetricsAction; 22 using base::UserMetricsAction;
22 using bookmarks::BookmarkNode; 23 using bookmarks::BookmarkNode;
23 24
24 namespace { 25 namespace {
25 26
26 // Padding on the right side of the arrow icon. 27 // Padding on the trailing side of the arrow icon.
27 const int kHierarchyButtonRightPadding = 4; 28 const int kHierarchyButtonTrailingPadding = 4;
28 29
29 // Padding on the left side of the arrow icon. 30 // Padding on the leading side of the arrow icon.
30 const int kHierarchyButtonLeftPadding = 11; 31 const int kHierarchyButtonLeadingPadding = 11;
31 32
32 const int kIconTextSpacer = 4; 33 const int kIconTextSpacer = 4;
33 const int kTextRightPadding = 4; 34 const int kTrailingPadding = 4;
34 const int kIconLeftPadding = 4; 35 const int kIconLeadingPadding = 4;
35 36
36 const int kDefaultFontSize = 12; 37 const int kDefaultFontSize = 12;
37 38
38 // Kerning value for the title text. 39 // Kerning value for the title text.
39 const CGFloat kKernAmount = 0.2; 40 const CGFloat kKernAmount = 0.2;
40 41
41 }; // namespace 42 }; // namespace
42 43
43 // TODO(lgrey): Bake setting the chevron image into this 44 // TODO(lgrey): Bake setting the chevron image into this
44 // class instead of setting it externally. 45 // class instead of setting it externally.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 112 }
112 113
113 + (id)offTheSideButtonCell { 114 + (id)offTheSideButtonCell {
114 return [[[OffTheSideButtonCell alloc] init] autorelease]; 115 return [[[OffTheSideButtonCell alloc] init] autorelease];
115 } 116 }
116 117
117 + (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node 118 + (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node
118 image:(NSImage*)image { 119 image:(NSImage*)image {
119 NSString* title = 120 NSString* title =
120 [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())]; 121 [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())];
121 CGFloat width = kIconLeftPadding + [image size].width; 122 CGFloat width = kIconLeadingPadding + [image size].width;
122 if ([title length] > 0) { 123 if ([title length] > 0) {
123 CGSize titleSize = [title sizeWithAttributes:@{ 124 CGSize titleSize = [title sizeWithAttributes:@{
124 NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell], 125 NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell],
125 NSKernAttributeName : @(kKernAmount), 126 NSKernAttributeName : @(kKernAmount),
126 NSFontAttributeName : [self fontForBookmarkBarCell], 127 NSFontAttributeName : [self fontForBookmarkBarCell],
127 }]; 128 }];
128 width += kIconTextSpacer + std::ceil(titleSize.width) + kTextRightPadding; 129 width += kIconTextSpacer + std::ceil(titleSize.width) + kTrailingPadding;
129 } else { 130 } else {
130 width += kIconLeftPadding; 131 width += kTrailingPadding;
131 } 132 }
132 return width; 133 return width;
133 } 134 }
134 135
135 - (id)initForNode:(const BookmarkNode*)node 136 - (id)initForNode:(const BookmarkNode*)node
136 text:(NSString*)text 137 text:(NSString*)text
137 image:(NSImage*)image 138 image:(NSImage*)image
138 menuController:(BookmarkContextMenuCocoaController*)menuController { 139 menuController:(BookmarkContextMenuCocoaController*)menuController {
139 if ((self = [super initTextCell:text])) { 140 if ((self = [super initTextCell:text])) {
140 menuController_ = menuController; 141 menuController_ = menuController;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 189
189 - (BOOL)isOffTheSideButtonCell { 190 - (BOOL)isOffTheSideButtonCell {
190 return NO; 191 return NO;
191 } 192 }
192 193
193 // Perform all normal init routines specific to the BookmarkButtonCell. 194 // Perform all normal init routines specific to the BookmarkButtonCell.
194 - (void)configureBookmarkButtonCell { 195 - (void)configureBookmarkButtonCell {
195 [self setButtonType:NSMomentaryPushInButton]; 196 [self setButtonType:NSMomentaryPushInButton];
196 [self setShowsBorderOnlyWhileMouseInside:YES]; 197 [self setShowsBorderOnlyWhileMouseInside:YES];
197 [self setControlSize:NSSmallControlSize]; 198 [self setControlSize:NSSmallControlSize];
198 [self setAlignment:NSLeftTextAlignment]; 199 [self setAlignment:NSNaturalTextAlignment];
199 [self setFont:[[self class] fontForBookmarkBarCell]]; 200 [self setFont:[[self class] fontForBookmarkBarCell]];
200 [self setBordered:NO]; 201 [self setBordered:NO];
201 [self setBezeled:NO]; 202 [self setBezeled:NO];
202 [self setWraps:NO]; 203 [self setWraps:NO];
203 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's 204 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's
204 // try to match Windows for a bit to see what happens. 205 // try to match Windows for a bit to see what happens.
205 [self setLineBreakMode:NSLineBreakByTruncatingTail]; 206 [self setLineBreakMode:NSLineBreakByTruncatingTail];
206 207
207 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled 208 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled
208 // at paint time without this. 209 // at paint time without this.
(...skipping 17 matching lines...) Expand all
226 NSSize size = [self cellSize]; 227 NSSize size = [self cellSize];
227 size.width = std::min(aRect.size.width, size.width); 228 size.width = std::min(aRect.size.width, size.width);
228 size.height = std::min(aRect.size.height, size.height); 229 size.height = std::min(aRect.size.height, size.height);
229 return size; 230 return size;
230 } 231 }
231 232
232 - (void)setBookmarkCellText:(NSString*)title 233 - (void)setBookmarkCellText:(NSString*)title
233 image:(NSImage*)image { 234 image:(NSImage*)image {
234 title = [[self class] cleanTitle:title]; 235 title = [[self class] cleanTitle:title];
235 if ([title length] && ![self isOffTheSideButtonCell]) { 236 if ([title length] && ![self isOffTheSideButtonCell]) {
236 [self setImagePosition:NSImageLeft]; 237 [self setImagePosition:cocoa_l10n_util::LeadingCellImagePosition()];
237 [self setTitle:title]; 238 [self setTitle:title];
238 } else if ([self isFolderButtonCell]) { 239 } else if ([self isFolderButtonCell]) {
239 // Left-align icons for bookmarks within folders, regardless of whether 240 // Left-align icons for bookmarks within folders, regardless of whether
240 // there is a title. 241 // there is a title.
241 [self setImagePosition:NSImageLeft]; 242 [self setImagePosition:cocoa_l10n_util::LeadingCellImagePosition()];
242 } else { 243 } else {
243 // For bookmarks without a title that aren't visible directly in the 244 // For bookmarks without a title that aren't visible directly in the
244 // bookmarks bar, squeeze things tighter by displaying only the image. 245 // bookmarks bar, squeeze things tighter by displaying only the image.
245 // By default, Cocoa leaves extra space in an attempt to display an 246 // By default, Cocoa leaves extra space in an attempt to display an
246 // empty title. 247 // empty title.
247 [self setImagePosition:NSImageOnly]; 248 [self setImagePosition:NSImageOnly];
248 } 249 }
249 250
250 if (image) 251 if (image)
251 [self setImage:image]; 252 [self setImage:image];
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 // See comment above mouseEntered:, above. 322 // See comment above mouseEntered:, above.
322 - (void)mouseExited:(NSEvent*)event { 323 - (void)mouseExited:(NSEvent*)event {
323 [[self controlView] mouseExited:event]; 324 [[self controlView] mouseExited:event];
324 [super mouseExited:event]; 325 [super mouseExited:event];
325 } 326 }
326 327
327 - (void)setDrawFolderArrow:(BOOL)draw { 328 - (void)setDrawFolderArrow:(BOOL)draw {
328 drawFolderArrow_ = draw; 329 drawFolderArrow_ = draw;
329 if (draw && !arrowImage_) { 330 if (draw && !arrowImage_) {
330 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 331 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
331 arrowImage_.reset( 332 NSImage* image =
332 [rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage() retain]); 333 rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage();
334 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
335 image = cocoa_l10n_util::FlippedImage(image);
336 arrowImage_.reset([image retain]);
333 } 337 }
334 } 338 }
335 339
336 - (NSDictionary*)titleTextAttributes { 340 - (NSDictionary*)titleTextAttributes {
337 NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell]; 341 NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell];
338 NSColor* textColor = textColor_.get(); 342 NSColor* textColor = textColor_.get();
339 if (!textColor) { 343 if (!textColor) {
340 textColor = [NSColor blackColor]; 344 textColor = [NSColor blackColor];
341 } 345 }
342 if (![self isEnabled]) { 346 if (![self isEnabled]) {
(...skipping 15 matching lines...) Expand all
358 - (NSString*)visibleTitle { 362 - (NSString*)visibleTitle {
359 return [self imagePosition] != NSImageOnly ? [self title] : @""; 363 return [self imagePosition] != NSImageOnly ? [self title] : @"";
360 } 364 }
361 365
362 // Add extra size for the arrow so it doesn't overlap the text. 366 // Add extra size for the arrow so it doesn't overlap the text.
363 // Does not sanity check to be sure this is actually a folder node. 367 // Does not sanity check to be sure this is actually a folder node.
364 - (NSSize)cellSize { 368 - (NSSize)cellSize {
365 NSSize cellSize = NSZeroSize; 369 NSSize cellSize = NSZeroSize;
366 // Return the space needed to display the image and title, with a little 370 // Return the space needed to display the image and title, with a little
367 // distance between them. 371 // distance between them.
368 cellSize = NSMakeSize(kIconLeftPadding + [[self image] size].width, 372 cellSize = NSMakeSize(kIconLeadingPadding + [[self image] size].width,
369 bookmarks::kBookmarkButtonHeight); 373 bookmarks::kBookmarkButtonHeight);
370 NSString* title = [self visibleTitle]; 374 NSString* title = [self visibleTitle];
371 if ([title length] > 0) { 375 if ([title length] > 0) {
372 CGFloat textWidth = 376 CGFloat textWidth =
373 [title sizeWithAttributes:[self titleTextAttributes]].width; 377 [title sizeWithAttributes:[self titleTextAttributes]].width;
374 cellSize.width += 378 cellSize.width += kIconTextSpacer + std::ceil(textWidth) + kTrailingPadding;
375 kIconTextSpacer + std::ceil(textWidth) + kTextRightPadding;
376 } else { 379 } else {
377 // Make buttons without visible titles 20pts wide (18 plus padding). 380 cellSize.width += kIconLeadingPadding;
378 cellSize.width += kIconLeftPadding;
379 } 381 }
380 382
381 if (drawFolderArrow_) { 383 if (drawFolderArrow_) {
382 cellSize.width += [arrowImage_ size].width + 384 cellSize.width += [arrowImage_ size].width +
383 kHierarchyButtonLeftPadding + 385 kHierarchyButtonLeadingPadding +
384 kHierarchyButtonRightPadding; 386 kHierarchyButtonTrailingPadding;
385 } 387 }
386 return cellSize; 388 return cellSize;
387 } 389 }
388 390
389 - (NSRect)imageRectForBounds:(NSRect)theRect { 391 - (NSRect)imageRectForBounds:(NSRect)theRect {
390 NSRect imageRect = [super imageRectForBounds:theRect]; 392 NSRect imageRect = [super imageRectForBounds:theRect];
391 // Add a little space between the image and the button's left edge, but only 393 const CGFloat inset = [self insetInView:[self controlView]];
392 // if there's a visible title.
393 imageRect.origin.y -= 1; 394 imageRect.origin.y -= 1;
394 imageRect.origin.x = kIconLeftPadding; 395 imageRect.origin.x =
396 cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
397 ? NSMaxX(theRect) - kIconLeadingPadding - NSWidth(imageRect) + inset
398 : kIconLeadingPadding;
395 return imageRect; 399 return imageRect;
396 } 400 }
397 401
398 - (CGFloat)textStartXOffset { 402 - (NSRect)titleRectForBounds:(NSRect)theRect {
399 return kIconLeftPadding + [[self image] size].width + kIconTextSpacer; 403 NSRect textRect = [super titleRectForBounds:theRect];
404 NSRect imageRect = [self imageRectForBounds:theRect];
405 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
406 textRect.origin.x = kTrailingPadding;
407 if (drawFolderArrow_) {
408 textRect.origin.x +=
409 [arrowImage_ size].width + kHierarchyButtonTrailingPadding;
410 }
411 textRect.size.width =
412 NSMinX(imageRect) - textRect.origin.x - kIconTextSpacer;
413 } else {
414 textRect.origin.x = NSMaxX(imageRect) + kIconTextSpacer;
415 }
416 return textRect;
400 } 417 }
401 418
402 - (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame 419 - (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame
403 inView:(NSView*)controlView { 420 inView:(NSView*)controlView {
404 // We have to adjust the focus ring slightly for the chevron and regular 421 // We have to adjust the focus ring slightly for the chevron and regular
405 // bookmark icons. 422 // bookmark icons.
406 if ([self isOffTheSideButtonCell]) { 423 if ([self isOffTheSideButtonCell]) {
407 cellFrame.origin.y -= 2; 424 cellFrame.origin.y -= 2;
408 } else if ([self visibleTitle].length > 0) { 425 } else if ([self visibleTitle].length > 0) {
409 cellFrame.origin.x += 4; 426 cellFrame.origin.x += 4;
(...skipping 11 matching lines...) Expand all
421 438
422 // If asked to do so, and if a folder, draw the arrow. 439 // If asked to do so, and if a folder, draw the arrow.
423 if (!drawFolderArrow_) 440 if (!drawFolderArrow_)
424 return; 441 return;
425 BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]); 442 BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]);
426 DCHECK([button respondsToSelector:@selector(isFolder)]); 443 DCHECK([button respondsToSelector:@selector(isFolder)]);
427 if ([button isFolder]) { 444 if ([button isFolder]) {
428 NSRect imageRect = NSZeroRect; 445 NSRect imageRect = NSZeroRect;
429 imageRect.size = [arrowImage_ size]; 446 imageRect.size = [arrowImage_ size];
430 const CGFloat kArrowOffset = 1.0; // Required for proper centering. 447 const CGFloat kArrowOffset = 1.0; // Required for proper centering.
431 CGFloat dX = 448 CGFloat dX = cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
432 NSWidth(cellFrame) - NSWidth(imageRect) - kHierarchyButtonRightPadding; 449 ? kHierarchyButtonTrailingPadding
450 : NSWidth(cellFrame) - NSWidth(imageRect) -
451 kHierarchyButtonTrailingPadding;
433 CGFloat dY = (NSHeight(cellFrame) / 2.0) - (NSHeight(imageRect) / 2.0) + 452 CGFloat dY = (NSHeight(cellFrame) / 2.0) - (NSHeight(imageRect) / 2.0) +
434 kArrowOffset; 453 kArrowOffset;
435 NSRect drawRect = NSOffsetRect(imageRect, dX, dY); 454 NSRect drawRect = NSOffsetRect(imageRect, dX, dY);
436 [arrowImage_ drawInRect:drawRect 455 [arrowImage_ drawInRect:drawRect
437 fromRect:imageRect 456 fromRect:imageRect
438 operation:NSCompositeSourceOver 457 operation:NSCompositeSourceOver
439 fraction:[self isEnabled] ? 1.0 : 0.5 458 fraction:[self isEnabled] ? 1.0 : 0.5
440 respectFlipped:YES 459 respectFlipped:YES
441 hints:nil]; 460 hints:nil];
442 } 461 }
(...skipping 27 matching lines...) Expand all
470 489
471 // Returns |title| with newlines and line feeds replaced with 490 // Returns |title| with newlines and line feeds replaced with
472 // spaces. 491 // spaces.
473 + (NSString*)cleanTitle:(NSString*)title { 492 + (NSString*)cleanTitle:(NSString*)title {
474 title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; 493 title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
475 title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "]; 494 title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "];
476 return title; 495 return title;
477 } 496 }
478 497
479 @end 498 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698