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