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

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: Go back to hardcoding image y offset 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 kTextTrailingPadding = 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } 113 }
113 114
114 + (id)offTheSideButtonCell { 115 + (id)offTheSideButtonCell {
115 return [[[OffTheSideButtonCell alloc] init] autorelease]; 116 return [[[OffTheSideButtonCell alloc] init] autorelease];
116 } 117 }
117 118
118 + (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node 119 + (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node
119 image:(NSImage*)image { 120 image:(NSImage*)image {
120 NSString* title = 121 NSString* title =
121 [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())]; 122 [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())];
122 CGFloat width = kIconLeftPadding + [image size].width; 123 CGFloat width = kIconLeadingPadding + [image size].width;
123 if ([title length] > 0) { 124 if ([title length] > 0) {
124 CGSize titleSize = [title sizeWithAttributes:@{ 125 CGSize titleSize = [title sizeWithAttributes:@{
125 NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell], 126 NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell],
126 NSKernAttributeName : @(kKernAmount), 127 NSKernAttributeName : @(kKernAmount),
127 NSFontAttributeName : [self fontForBookmarkBarCell], 128 NSFontAttributeName : [self fontForBookmarkBarCell],
128 }]; 129 }];
129 width += kIconTextSpacer + std::ceil(titleSize.width) + kTextRightPadding; 130 width +=
131 kIconTextSpacer + std::ceil(titleSize.width) + kTextTrailingPadding;
130 } else { 132 } else {
131 width += kIconLeftPadding; 133 width += kIconLeadingPadding;
Elly Fong-Jones 2017/05/03 17:03:14 why is this leading padding twice? shouldn't it al
lgrey 2017/05/03 21:32:48 Done.
132 } 134 }
133 return width; 135 return width;
134 } 136 }
135 137
136 - (id)initForNode:(const BookmarkNode*)node 138 - (id)initForNode:(const BookmarkNode*)node
137 text:(NSString*)text 139 text:(NSString*)text
138 image:(NSImage*)image 140 image:(NSImage*)image
139 menuController:(BookmarkContextMenuCocoaController*)menuController { 141 menuController:(BookmarkContextMenuCocoaController*)menuController {
140 if ((self = [super initTextCell:text])) { 142 if ((self = [super initTextCell:text])) {
141 menuController_ = menuController; 143 menuController_ = menuController;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 191
190 - (BOOL)isOffTheSideButtonCell { 192 - (BOOL)isOffTheSideButtonCell {
191 return NO; 193 return NO;
192 } 194 }
193 195
194 // Perform all normal init routines specific to the BookmarkButtonCell. 196 // Perform all normal init routines specific to the BookmarkButtonCell.
195 - (void)configureBookmarkButtonCell { 197 - (void)configureBookmarkButtonCell {
196 [self setButtonType:NSMomentaryPushInButton]; 198 [self setButtonType:NSMomentaryPushInButton];
197 [self setShowsBorderOnlyWhileMouseInside:YES]; 199 [self setShowsBorderOnlyWhileMouseInside:YES];
198 [self setControlSize:NSSmallControlSize]; 200 [self setControlSize:NSSmallControlSize];
199 [self setAlignment:NSLeftTextAlignment];
200 [self setFont:[[self class] fontForBookmarkBarCell]]; 201 [self setFont:[[self class] fontForBookmarkBarCell]];
202 [self setAlignment:NSNaturalTextAlignment];
Elly Fong-Jones 2017/05/03 17:03:14 why did this move? is it important that these be d
lgrey 2017/05/03 21:32:48 I think this was an accident, doesn't seem to make
201 [self setBordered:NO]; 203 [self setBordered:NO];
202 [self setBezeled:NO]; 204 [self setBezeled:NO];
203 [self setWraps:NO]; 205 [self setWraps:NO];
204 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's 206 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's
205 // try to match Windows for a bit to see what happens. 207 // try to match Windows for a bit to see what happens.
206 [self setLineBreakMode:NSLineBreakByTruncatingTail]; 208 [self setLineBreakMode:NSLineBreakByTruncatingTail];
207 209
208 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled 210 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled
209 // at paint time without this. 211 // at paint time without this.
210 [self setImageScaling:NSImageScaleNone]; 212 [self setImageScaling:NSImageScaleNone];
(...skipping 16 matching lines...) Expand all
227 NSSize size = [self cellSize]; 229 NSSize size = [self cellSize];
228 size.width = std::min(aRect.size.width, size.width); 230 size.width = std::min(aRect.size.width, size.width);
229 size.height = std::min(aRect.size.height, size.height); 231 size.height = std::min(aRect.size.height, size.height);
230 return size; 232 return size;
231 } 233 }
232 234
233 - (void)setBookmarkCellText:(NSString*)title 235 - (void)setBookmarkCellText:(NSString*)title
234 image:(NSImage*)image { 236 image:(NSImage*)image {
235 title = [[self class] cleanTitle:title]; 237 title = [[self class] cleanTitle:title];
236 if ([title length] && ![self isOffTheSideButtonCell]) { 238 if ([title length] && ![self isOffTheSideButtonCell]) {
237 [self setImagePosition:NSImageLeft]; 239 [self setImagePosition:cocoa_l10n_util::LeadingCellImagePosition()];
238 [self setTitle:title]; 240 [self setTitle:title];
239 } else if ([self isFolderButtonCell]) { 241 } else if ([self isFolderButtonCell]) {
240 // Left-align icons for bookmarks within folders, regardless of whether 242 // Left-align icons for bookmarks within folders, regardless of whether
241 // there is a title. 243 // there is a title.
242 [self setImagePosition:NSImageLeft]; 244 [self setImagePosition:cocoa_l10n_util::LeadingCellImagePosition()];
243 } else { 245 } else {
244 // For bookmarks without a title that aren't visible directly in the 246 // For bookmarks without a title that aren't visible directly in the
245 // bookmarks bar, squeeze things tighter by displaying only the image. 247 // bookmarks bar, squeeze things tighter by displaying only the image.
246 // By default, Cocoa leaves extra space in an attempt to display an 248 // By default, Cocoa leaves extra space in an attempt to display an
247 // empty title. 249 // empty title.
248 [self setImagePosition:NSImageOnly]; 250 [self setImagePosition:NSImageOnly];
249 } 251 }
250 252
251 if (image) 253 if (image)
252 [self setImage:image]; 254 [self setImage:image];
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 // See comment above mouseEntered:, above. 324 // See comment above mouseEntered:, above.
323 - (void)mouseExited:(NSEvent*)event { 325 - (void)mouseExited:(NSEvent*)event {
324 [[self controlView] mouseExited:event]; 326 [[self controlView] mouseExited:event];
325 [super mouseExited:event]; 327 [super mouseExited:event];
326 } 328 }
327 329
328 - (void)setDrawFolderArrow:(BOOL)draw { 330 - (void)setDrawFolderArrow:(BOOL)draw {
329 drawFolderArrow_ = draw; 331 drawFolderArrow_ = draw;
330 if (draw && !arrowImage_) { 332 if (draw && !arrowImage_) {
331 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 333 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
332 arrowImage_.reset( 334 NSImage* image =
333 [rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage() retain]); 335 rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage();
336 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
337 image = cocoa_l10n_util::FlippedImage(image);
338 arrowImage_.reset([image retain]);
334 } 339 }
335 } 340 }
336 341
337 - (NSDictionary*)titleTextAttributes { 342 - (NSDictionary*)titleTextAttributes {
338 NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell]; 343 NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell];
339 NSColor* textColor = textColor_.get(); 344 NSColor* textColor = textColor_.get();
340 if (!textColor) { 345 if (!textColor) {
341 textColor = [NSColor blackColor]; 346 textColor = [NSColor blackColor];
342 } 347 }
343 if (![self isEnabled]) { 348 if (![self isEnabled]) {
(...skipping 15 matching lines...) Expand all
359 - (NSString*)visibleTitle { 364 - (NSString*)visibleTitle {
360 return [self imagePosition] != NSImageOnly ? [self title] : @""; 365 return [self imagePosition] != NSImageOnly ? [self title] : @"";
361 } 366 }
362 367
363 // Add extra size for the arrow so it doesn't overlap the text. 368 // Add extra size for the arrow so it doesn't overlap the text.
364 // Does not sanity check to be sure this is actually a folder node. 369 // Does not sanity check to be sure this is actually a folder node.
365 - (NSSize)cellSize { 370 - (NSSize)cellSize {
366 NSSize cellSize = NSZeroSize; 371 NSSize cellSize = NSZeroSize;
367 // Return the space needed to display the image and title, with a little 372 // Return the space needed to display the image and title, with a little
368 // distance between them. 373 // distance between them.
369 cellSize = NSMakeSize(kIconLeftPadding + [[self image] size].width, 374 cellSize = NSMakeSize(kIconLeadingPadding + [[self image] size].width,
370 bookmarks::kBookmarkButtonHeight); 375 bookmarks::kBookmarkButtonHeight);
371 NSString* title = [self visibleTitle]; 376 NSString* title = [self visibleTitle];
372 if ([title length] > 0) { 377 if ([title length] > 0) {
373 CGFloat textWidth = 378 CGFloat textWidth =
374 [title sizeWithAttributes:[self titleTextAttributes]].width; 379 [title sizeWithAttributes:[self titleTextAttributes]].width;
375 cellSize.width += 380 cellSize.width +=
376 kIconTextSpacer + std::ceil(textWidth) + kTextRightPadding; 381 kIconTextSpacer + std::ceil(textWidth) + kTextTrailingPadding;
377 } else { 382 } else {
378 // Make buttons without visible titles 20pts wide (18 plus padding). 383 // Make buttons without visible titles 20pts wide (18 plus padding).
Elly Fong-Jones 2017/05/03 17:03:14 please delete this comment! comments that duplicat
lgrey 2017/05/03 21:32:48 Done.
379 cellSize.width += kIconLeftPadding; 384 cellSize.width += kIconLeadingPadding;
380 } 385 }
381 386
382 if (drawFolderArrow_) { 387 if (drawFolderArrow_) {
383 cellSize.width += [arrowImage_ size].width + 388 cellSize.width += [arrowImage_ size].width +
384 kHierarchyButtonLeftPadding + 389 kHierarchyButtonLeadingPadding +
385 kHierarchyButtonRightPadding; 390 kHierarchyButtonTrailingPadding;
386 } 391 }
387 return cellSize; 392 return cellSize;
388 } 393 }
389 394
390 - (NSRect)imageRectForBounds:(NSRect)theRect { 395 - (NSRect)imageRectForBounds:(NSRect)theRect {
391 NSRect imageRect = [super imageRectForBounds:theRect]; 396 NSRect imageRect = [super imageRectForBounds:theRect];
392 // Add a little space between the image and the button's left edge, but only 397 const CGFloat inset = [self insetInView:[self controlView]];
393 // if there's a visible title.
394 imageRect.origin.y -= 1; 398 imageRect.origin.y -= 1;
395 imageRect.origin.x = kIconLeftPadding; 399 imageRect.origin.x =
400 cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
401 ? NSMaxX(theRect) - kIconLeadingPadding - NSWidth(imageRect) + inset
402 : kIconLeadingPadding;
396 return imageRect; 403 return imageRect;
397 } 404 }
398 405
399 - (CGFloat)textStartXOffset { 406 - (NSRect)titleRectForBounds:(NSRect)theRect {
400 return kIconLeftPadding + [[self image] size].width + kIconTextSpacer; 407 NSRect textRect = [super titleRectForBounds:theRect];
408 NSRect imageRect = [self imageRectForBounds:theRect];
409 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
410 textRect.origin.x = drawFolderArrow_ ? [arrowImage_ size].width +
411 kHierarchyButtonTrailingPadding +
412 kTextTrailingPadding
413 : kTextTrailingPadding;
414 textRect.size.width =
415 NSMinX(imageRect) - textRect.origin.x - kIconTextSpacer;
416 } else {
417 textRect.origin.x = NSMaxX(imageRect) + kIconTextSpacer;
418 }
419 return textRect;
401 } 420 }
402 421
403 - (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame 422 - (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame
404 inView:(NSView*)controlView { 423 inView:(NSView*)controlView {
405 // We have to adjust the focus ring slightly for the chevron and regular 424 // We have to adjust the focus ring slightly for the chevron and regular
406 // bookmark icons. 425 // bookmark icons.
407 if ([self isOffTheSideButtonCell]) { 426 if ([self isOffTheSideButtonCell]) {
408 cellFrame.origin.y -= 2; 427 cellFrame.origin.y -= 2;
409 } else if ([self visibleTitle].length > 0) { 428 } else if ([self visibleTitle].length > 0) {
410 cellFrame.origin.x += 4; 429 cellFrame.origin.x += 4;
(...skipping 11 matching lines...) Expand all
422 441
423 // If asked to do so, and if a folder, draw the arrow. 442 // If asked to do so, and if a folder, draw the arrow.
424 if (!drawFolderArrow_) 443 if (!drawFolderArrow_)
425 return; 444 return;
426 BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]); 445 BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]);
427 DCHECK([button respondsToSelector:@selector(isFolder)]); 446 DCHECK([button respondsToSelector:@selector(isFolder)]);
428 if ([button isFolder]) { 447 if ([button isFolder]) {
429 NSRect imageRect = NSZeroRect; 448 NSRect imageRect = NSZeroRect;
430 imageRect.size = [arrowImage_ size]; 449 imageRect.size = [arrowImage_ size];
431 const CGFloat kArrowOffset = 1.0; // Required for proper centering. 450 const CGFloat kArrowOffset = 1.0; // Required for proper centering.
432 CGFloat dX = 451 CGFloat dX = cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
433 NSWidth(cellFrame) - NSWidth(imageRect) - kHierarchyButtonRightPadding; 452 ? kHierarchyButtonTrailingPadding
453 : NSWidth(cellFrame) - NSWidth(imageRect) -
454 kHierarchyButtonTrailingPadding;
434 CGFloat dY = (NSHeight(cellFrame) / 2.0) - (NSHeight(imageRect) / 2.0) + 455 CGFloat dY = (NSHeight(cellFrame) / 2.0) - (NSHeight(imageRect) / 2.0) +
435 kArrowOffset; 456 kArrowOffset;
436 NSRect drawRect = NSOffsetRect(imageRect, dX, dY); 457 NSRect drawRect = NSOffsetRect(imageRect, dX, dY);
437 [arrowImage_ drawInRect:drawRect 458 [arrowImage_ drawInRect:drawRect
438 fromRect:imageRect 459 fromRect:imageRect
439 operation:NSCompositeSourceOver 460 operation:NSCompositeSourceOver
440 fraction:[self isEnabled] ? 1.0 : 0.5 461 fraction:[self isEnabled] ? 1.0 : 0.5
441 respectFlipped:YES 462 respectFlipped:YES
442 hints:nil]; 463 hints:nil];
443 } 464 }
(...skipping 27 matching lines...) Expand all
471 492
472 // Returns |title| with newlines and line feeds replaced with 493 // Returns |title| with newlines and line feeds replaced with
473 // spaces. 494 // spaces.
474 + (NSString*)cleanTitle:(NSString*)title { 495 + (NSString*)cleanTitle:(NSString*)title {
475 title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; 496 title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
476 title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "]; 497 title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "];
477 return title; 498 return title;
478 } 499 }
479 500
480 @end 501 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698