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

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

Issue 2751573002: [Mac] Refactor bookmark bar controller (Closed)
Patch Set: Restore unused button pool Created 3 years, 9 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/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" 9 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
10 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h" 10 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
(...skipping 19 matching lines...) Expand all
30 const int kHierarchyButtonLeftPadding = 11; 30 const int kHierarchyButtonLeftPadding = 11;
31 31
32 const int kIconTextSpacer = 4; 32 const int kIconTextSpacer = 4;
33 const int kTextRightPadding = 4; 33 const int kTextRightPadding = 4;
34 const int kIconLeftPadding = 4; 34 const int kIconLeftPadding = 4;
35 35
36 const int kDefaultFontSize = 12; 36 const int kDefaultFontSize = 12;
37 37
38 }; // namespace 38 }; // namespace
39 39
40 @interface BookmarkButtonCell (Private)
41 // Returns YES if the cell is the offTheSide button cell.
42 - (BOOL)isOffTheSideButtonCell;
43 - (void)configureBookmarkButtonCell;
44 - (void)applyTextColor;
45 // Returns the title the button cell displays. Note that a button cell can
46 // have a title string assigned but it won't be visible if its image position
47 // is NSImageOnly.
48 - (NSString*)visibleTitle;
49 // Returns the dictionary of attributes to associate with the button title.
50 - (NSDictionary*)titleTextAttributes;
51 @end
52
40 // TODO(lgrey): Bake setting the chevron image into this 53 // TODO(lgrey): Bake setting the chevron image into this
41 // class instead of setting it externally. 54 // class instead of setting it externally.
42 @interface OffTheSideButtonCell : BookmarkButtonCell 55 @interface OffTheSideButtonCell : BookmarkButtonCell
43 56
44 - (NSString*)accessibilityTitle; 57 - (NSString*)accessibilityTitle;
45 58
46 @end 59 @end
47 @implementation OffTheSideButtonCell 60 @implementation OffTheSideButtonCell
48 61
49 - (BOOL)isOffTheSideButtonCell { 62 - (BOOL)isOffTheSideButtonCell {
50 return YES; 63 return YES;
51 } 64 }
52 65
53 - (NSString*)accessibilityTitle { 66 - (NSString*)accessibilityTitle {
54 return l10n_util::GetNSString(IDS_ACCNAME_BOOKMARKS_CHEVRON); 67 return l10n_util::GetNSString(IDS_ACCNAME_BOOKMARKS_CHEVRON);
55 } 68 }
56 69
57 - (NSRect)imageRectForBounds:(NSRect)theRect { 70 - (NSRect)imageRectForBounds:(NSRect)theRect {
58 NSRect imageRect = [super imageRectForBounds:theRect]; 71 NSRect imageRect = [super imageRectForBounds:theRect];
59 // Make sure the chevron icon stays centered. Normally a bookmark bar item 72 // Make sure the chevron icon stays centered. Normally a bookmark bar item
60 // with no label has its icon placed at a fixed x-position. 73 // with no label has its icon placed at a fixed x-position.
61 CGFloat totalWidth = NSMaxX(theRect); 74 CGFloat totalWidth = NSMaxX(theRect);
62 imageRect.origin.x = (totalWidth - [self image].size.width) / 2; 75 imageRect.origin.x = (totalWidth - [self image].size.width) / 2;
63 return imageRect; 76 return imageRect;
64 } 77 }
65 78
66 @end 79 @end
67 80
68 @interface BookmarkButtonCell(Private)
69 // Returns YES if the cell is the offTheSide button cell.
70 - (BOOL)isOffTheSideButtonCell;
71 - (void)configureBookmarkButtonCell;
72 - (void)applyTextColor;
73 // Returns the title the button cell displays. Note that a button cell can
74 // have a title string assigned but it won't be visible if its image position
75 // is NSImageOnly.
76 - (NSString*)visibleTitle;
77 // Returns the dictionary of attributes to associate with the button title.
78 - (NSDictionary*)titleTextAttributes;
79 @end
80
81 81
82 @implementation BookmarkButtonCell 82 @implementation BookmarkButtonCell
83 83
84 @synthesize startingChildIndex = startingChildIndex_; 84 @synthesize startingChildIndex = startingChildIndex_;
85 @synthesize drawFolderArrow = drawFolderArrow_; 85 @synthesize drawFolderArrow = drawFolderArrow_;
86 86
87 + (id)buttonCellForNode:(const BookmarkNode*)node 87 + (id)buttonCellForNode:(const BookmarkNode*)node
88 text:(NSString*)text 88 text:(NSString*)text
89 image:(NSImage*)image 89 image:(NSImage*)image
90 menuController:(BookmarkContextMenuCocoaController*)menuController { 90 menuController:(BookmarkContextMenuCocoaController*)menuController {
(...skipping 14 matching lines...) Expand all
105 image:image 105 image:image
106 menuController:menuController] 106 menuController:menuController]
107 autorelease]; 107 autorelease];
108 return buttonCell; 108 return buttonCell;
109 } 109 }
110 110
111 + (id)offTheSideButtonCell { 111 + (id)offTheSideButtonCell {
112 return [[[OffTheSideButtonCell alloc] init] autorelease]; 112 return [[[OffTheSideButtonCell alloc] init] autorelease];
113 } 113 }
114 114
115 + (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node
116 image:(NSImage*)image {
117 NSString* title =
118 [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())];
119 CGFloat width = kIconLeftPadding + [image size].width;
120 if ([title length] > 0) {
121 CGSize titleSize = [title sizeWithAttributes:@{
122 NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell]
123 }];
124 width += kIconTextSpacer + std::ceil(titleSize.width) + kTextRightPadding;
125 } else {
126 width += kIconLeftPadding;
127 }
128 return width;
129 }
130
115 - (id)initForNode:(const BookmarkNode*)node 131 - (id)initForNode:(const BookmarkNode*)node
116 text:(NSString*)text 132 text:(NSString*)text
117 image:(NSImage*)image 133 image:(NSImage*)image
118 menuController:(BookmarkContextMenuCocoaController*)menuController { 134 menuController:(BookmarkContextMenuCocoaController*)menuController {
119 if ((self = [super initTextCell:text])) { 135 if ((self = [super initTextCell:text])) {
120 menuController_ = menuController; 136 menuController_ = menuController;
121 [self configureBookmarkButtonCell]; 137 [self configureBookmarkButtonCell];
122 [self setTextColor:[NSColor blackColor]]; 138 [self setTextColor:[NSColor blackColor]];
123 [self setBookmarkNode:node]; 139 [self setBookmarkNode:node image:image];
124 // When opening a bookmark folder, the default behavior is that the 140 // When opening a bookmark folder, the default behavior is that the
125 // favicon is greyed when menu item is hovered with the mouse cursor. 141 // favicon is greyed when menu item is hovered with the mouse cursor.
126 // When using NSNoCellMask, the favicon won't be greyed when menu item 142 // When using NSNoCellMask, the favicon won't be greyed when menu item
127 // is hovered. 143 // is hovered.
128 // In the bookmark bar, the favicon is not greyed when the bookmark is 144 // In the bookmark bar, the favicon is not greyed when the bookmark is
129 // hovered with the mouse cursor. 145 // hovered with the mouse cursor.
130 // It makes the behavior of the bookmark folder consistent with hovering 146 // It makes the behavior of the bookmark folder consistent with hovering
131 // on the bookmark bar. 147 // on the bookmark bar.
132 [self setHighlightsBy:NSNoCellMask]; 148 [self setHighlightsBy:NSNoCellMask];
133
134 if (node) {
135 NSString* title = base::SysUTF16ToNSString(node->GetTitle());
136 [self setBookmarkCellText:title image:image];
137 } else {
138 [self setEmpty:YES];
139 [self setBookmarkCellText:l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU)
140 image:nil];
141 }
142 } 149 }
143 150
144 return self; 151 return self;
145 } 152 }
146 153
147 - (id)initWithText:(NSString*)text 154 - (id)initWithText:(NSString*)text
148 image:(NSImage*)image 155 image:(NSImage*)image
149 menuController:(BookmarkContextMenuCocoaController*)menuController { 156 menuController:(BookmarkContextMenuCocoaController*)menuController {
150 if ((self = [super initTextCell:text])) { 157 if ((self = [super initTextCell:text])) {
151 menuController_ = menuController; 158 menuController_ = menuController;
(...skipping 26 matching lines...) Expand all
178 - (BOOL)isOffTheSideButtonCell { 185 - (BOOL)isOffTheSideButtonCell {
179 return NO; 186 return NO;
180 } 187 }
181 188
182 // Perform all normal init routines specific to the BookmarkButtonCell. 189 // Perform all normal init routines specific to the BookmarkButtonCell.
183 - (void)configureBookmarkButtonCell { 190 - (void)configureBookmarkButtonCell {
184 [self setButtonType:NSMomentaryPushInButton]; 191 [self setButtonType:NSMomentaryPushInButton];
185 [self setShowsBorderOnlyWhileMouseInside:YES]; 192 [self setShowsBorderOnlyWhileMouseInside:YES];
186 [self setControlSize:NSSmallControlSize]; 193 [self setControlSize:NSSmallControlSize];
187 [self setAlignment:NSLeftTextAlignment]; 194 [self setAlignment:NSLeftTextAlignment];
188 [self setFont:[NSFont systemFontOfSize:kDefaultFontSize]]; 195 [self setFont:[[self class] fontForBookmarkBarCell]];
189 [self setBordered:NO]; 196 [self setBordered:NO];
190 [self setBezeled:NO]; 197 [self setBezeled:NO];
191 [self setWraps:NO]; 198 [self setWraps:NO];
192 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's 199 // NSLineBreakByTruncatingMiddle seems more common on OSX but let's
193 // try to match Windows for a bit to see what happens. 200 // try to match Windows for a bit to see what happens.
194 [self setLineBreakMode:NSLineBreakByTruncatingTail]; 201 [self setLineBreakMode:NSLineBreakByTruncatingTail];
195 202
196 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled 203 // The overflow button chevron bitmap is not 16 units high, so it'd be scaled
197 // at paint time without this. 204 // at paint time without this.
198 [self setImageScaling:NSImageScaleNone]; 205 [self setImageScaling:NSImageScaleNone];
(...skipping 14 matching lines...) Expand all
213 - (NSSize)cellSizeForBounds:(NSRect)aRect { 220 - (NSSize)cellSizeForBounds:(NSRect)aRect {
214 // There's no bezel or border so return cellSize. 221 // There's no bezel or border so return cellSize.
215 NSSize size = [self cellSize]; 222 NSSize size = [self cellSize];
216 size.width = std::min(aRect.size.width, size.width); 223 size.width = std::min(aRect.size.width, size.width);
217 size.height = std::min(aRect.size.height, size.height); 224 size.height = std::min(aRect.size.height, size.height);
218 return size; 225 return size;
219 } 226 }
220 227
221 - (void)setBookmarkCellText:(NSString*)title 228 - (void)setBookmarkCellText:(NSString*)title
222 image:(NSImage*)image { 229 image:(NSImage*)image {
223 title = [title stringByReplacingOccurrencesOfString:@"\n" 230 title = [[self class] cleanTitle:title];
224 withString:@" "]; 231 if ([title length] && ![self isOffTheSideButtonCell]) {
225 title = [title stringByReplacingOccurrencesOfString:@"\r"
226 withString:@" "];
227
228 if ([title length]) {
229 [self setImagePosition:NSImageLeft]; 232 [self setImagePosition:NSImageLeft];
230 [self setTitle:title]; 233 [self setTitle:title];
231 } else if ([self isFolderButtonCell]) { 234 } else if ([self isFolderButtonCell]) {
232 // Left-align icons for bookmarks within folders, regardless of whether 235 // Left-align icons for bookmarks within folders, regardless of whether
233 // there is a title. 236 // there is a title.
234 [self setImagePosition:NSImageLeft]; 237 [self setImagePosition:NSImageLeft];
235 } else { 238 } else {
236 // For bookmarks without a title that aren't visible directly in the 239 // For bookmarks without a title that aren't visible directly in the
237 // bookmarks bar, squeeze things tighter by displaying only the image. 240 // bookmarks bar, squeeze things tighter by displaying only the image.
238 // By default, Cocoa leaves extra space in an attempt to display an 241 // By default, Cocoa leaves extra space in an attempt to display an
239 // empty title. 242 // empty title.
240 [self setImagePosition:NSImageOnly]; 243 [self setImagePosition:NSImageOnly];
241 } 244 }
242 245
243 if (image) 246 if (image)
244 [self setImage:image]; 247 [self setImage:image];
245 } 248 }
246 249
247 - (void)setBookmarkNode:(const BookmarkNode*)node { 250 - (void)setBookmarkNode:(const BookmarkNode*)node {
251 [self setBookmarkNode:node image:nil];
252 }
253
254 - (void)setBookmarkNode:(const BookmarkNode*)node image:(NSImage*)image {
248 [self setRepresentedObject:[NSValue valueWithPointer:node]]; 255 [self setRepresentedObject:[NSValue valueWithPointer:node]];
256 if (node) {
257 NSString* title = base::SysUTF16ToNSString(node->GetTitle());
258 [self setBookmarkCellText:title image:image];
259 } else {
260 [self setEmpty:YES];
261 [self setBookmarkCellText:l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU)
262 image:nil];
263 }
249 } 264 }
250 265
251 - (const BookmarkNode*)bookmarkNode { 266 - (const BookmarkNode*)bookmarkNode {
252 return static_cast<const BookmarkNode*>([[self representedObject] 267 return static_cast<const BookmarkNode*>([[self representedObject]
253 pointerValue]); 268 pointerValue]);
254 } 269 }
255 270
256 - (NSMenu*)menu { 271 - (NSMenu*)menu {
257 // If node is NULL, this is a custom button, the menu does not represent 272 // If node is NULL, this is a custom button, the menu does not represent
258 // anything. 273 // anything.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 - (void)setDrawFolderArrow:(BOOL)draw { 323 - (void)setDrawFolderArrow:(BOOL)draw {
309 drawFolderArrow_ = draw; 324 drawFolderArrow_ = draw;
310 if (draw && !arrowImage_) { 325 if (draw && !arrowImage_) {
311 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 326 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
312 arrowImage_.reset( 327 arrowImage_.reset(
313 [rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage() retain]); 328 [rb.GetNativeImageNamed(IDR_MENU_HIERARCHY_ARROW).ToNSImage() retain]);
314 } 329 }
315 } 330 }
316 331
317 - (NSDictionary*)titleTextAttributes { 332 - (NSDictionary*)titleTextAttributes {
318 base::scoped_nsobject<NSMutableParagraphStyle> style( 333 NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell];
319 [NSMutableParagraphStyle new]);
320 [style setAlignment:NSNaturalTextAlignment];
321 [style setLineBreakMode:NSLineBreakByTruncatingTail];
322 NSColor* textColor = textColor_.get(); 334 NSColor* textColor = textColor_.get();
323 if (!textColor) { 335 if (!textColor) {
324 textColor = [NSColor blackColor]; 336 textColor = [NSColor blackColor];
325 } 337 }
326 if (![self isEnabled]) { 338 if (![self isEnabled]) {
327 textColor = [textColor colorWithAlphaComponent:0.5]; 339 textColor = [textColor colorWithAlphaComponent:0.5];
328 } 340 }
329 NSFont* theFont = [self font]; 341 NSFont* theFont = [self font];
330 if (!theFont) { 342 if (!theFont) {
331 theFont = [NSFont systemFontOfSize:kDefaultFontSize]; 343 theFont = [NSFont systemFontOfSize:kDefaultFontSize];
332 } 344 }
333 345
334 return @{ 346 return @{
335 NSFontAttributeName : theFont, 347 NSFontAttributeName : theFont,
336 NSForegroundColorAttributeName : textColor, 348 NSForegroundColorAttributeName : textColor,
337 NSParagraphStyleAttributeName : style.get(), 349 NSParagraphStyleAttributeName : style,
338 NSKernAttributeName : [NSNumber numberWithFloat:0.2] 350 NSKernAttributeName : [NSNumber numberWithFloat:0.2]
339 }; 351 };
340 } 352 }
341 353
342 - (NSString*)visibleTitle { 354 - (NSString*)visibleTitle {
343 return [self imagePosition] != NSImageOnly ? [self title] : @""; 355 return [self imagePosition] != NSImageOnly ? [self title] : @"";
344 } 356 }
345 357
346 // Add extra size for the arrow so it doesn't overlap the text. 358 // Add extra size for the arrow so it doesn't overlap the text.
347 // Does not sanity check to be sure this is actually a folder node. 359 // Does not sanity check to be sure this is actually a folder node.
348 - (NSSize)cellSize { 360 - (NSSize)cellSize {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 // In Material Design on Retina, and not in a folder menu, nudge the hover 446 // In Material Design on Retina, and not in a folder menu, nudge the hover
435 // background by 1px. 447 // background by 1px.
436 const CGFloat kLineWidth = [controlView cr_lineWidth]; 448 const CGFloat kLineWidth = [controlView cr_lineWidth];
437 if ([self isMaterialDesignButtonType] && ![self isFolderButtonCell] && 449 if ([self isMaterialDesignButtonType] && ![self isFolderButtonCell] &&
438 kLineWidth < 1) { 450 kLineWidth < 1) {
439 return -kLineWidth; 451 return -kLineWidth;
440 } 452 }
441 return 0.0; 453 return 0.0;
442 } 454 }
443 455
456 + (NSFont*)fontForBookmarkBarCell {
Elly Fong-Jones 2017/03/23 15:40:22 I like this pattern of breaking sorta-constants ou
457 return [NSFont systemFontOfSize:kDefaultFontSize];
458 }
459
460 + (NSParagraphStyle*)paragraphStyleForBookmarkBarCell {
461 NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
462 [style setAlignment:NSNaturalTextAlignment];
463 [style setLineBreakMode:NSLineBreakByTruncatingTail];
464 return [style autorelease];
465 }
466
467 // Returns |title| with newlines and line feeds replaced with
468 // spaces.
469 + (NSString*)cleanTitle:(NSString*)title {
470 title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
471 title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "];
472 return title;
473 }
444 474
445 @end 475 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698