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

Side by Side Diff: chrome/browser/cocoa/bookmark_bar_controller.mm

Issue 348017: Add the "Other bookmarks" button on the right of the bookmark bar.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "app/l10n_util_mac.h" 5 #include "app/l10n_util_mac.h"
6 #include "app/resource_bundle.h" 6 #include "app/resource_bundle.h"
7 #include "base/mac_util.h" 7 #include "base/mac_util.h"
8 #include "base/sys_string_conversions.h" 8 #include "base/sys_string_conversions.h"
9 #include "chrome/browser/bookmarks/bookmark_editor.h" 9 #include "chrome/browser/bookmarks/bookmark_editor.h"
10 #include "chrome/browser/bookmarks/bookmark_model.h" 10 #include "chrome/browser/bookmarks/bookmark_model.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 @end 45 @end
46 46
47 @interface BookmarkBarController(Private) 47 @interface BookmarkBarController(Private)
48 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; 48 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately;
49 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; 49 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately;
50 - (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu; 50 - (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu;
51 - (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu; 51 - (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu;
52 - (void)tagEmptyMenu:(NSMenu*)menu; 52 - (void)tagEmptyMenu:(NSMenu*)menu;
53 - (void)clearMenuTagMap; 53 - (void)clearMenuTagMap;
54 - (int)preferredHeight; 54 - (int)preferredHeight;
55 - (void)addNonBookmarkButtonsToView;
56 - (void)addButtonsToView;
57 - (void)resizeButtons;
58 - (void)centerNoItemsLabel;
55 @end 59 @end
56 60
57 @implementation BookmarkBarController 61 @implementation BookmarkBarController
58 62
59 - (id)initWithBrowser:(Browser*)browser 63 - (id)initWithBrowser:(Browser*)browser
60 initialWidth:(float)initialWidth 64 initialWidth:(float)initialWidth
61 compressDelegate:(id<ToolbarCompressable>)compressDelegate 65 compressDelegate:(id<ToolbarCompressable>)compressDelegate
62 resizeDelegate:(id<ViewResizer>)resizeDelegate 66 resizeDelegate:(id<ViewResizer>)resizeDelegate
63 urlDelegate:(id<BookmarkURLOpener>)urlDelegate { 67 urlDelegate:(id<BookmarkURLOpener>)urlDelegate {
64 if ((self = [super initWithNibName:@"BookmarkBar" 68 if ((self = [super initWithNibName:@"BookmarkBar"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 // expects. We will resize ourselves open later if needed. 102 // expects. We will resize ourselves open later if needed.
99 [[self view] setFrame:NSMakeRect(0, 0, initialWidth_, 0)]; 103 [[self view] setFrame:NSMakeRect(0, 0, initialWidth_, 0)];
100 104
101 // We are enabled by default. 105 // We are enabled by default.
102 barIsEnabled_ = YES; 106 barIsEnabled_ = YES;
103 107
104 // Don't pass ourself along (as 'self') until our init is completely 108 // Don't pass ourself along (as 'self') until our init is completely
105 // done. Thus, this call is (almost) last. 109 // done. Thus, this call is (almost) last.
106 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); 110 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_));
107 111
112 DCHECK([offTheSideButton_ attachedMenu]);
113
114 // To make life happier when the bookmark bar is floating, the
115 // chevron is a child of the button view.
116 [offTheSideButton_ removeFromSuperview];
117 [buttonView_ addSubview:offTheSideButton_];
118
108 // When resized we may need to add new buttons, or remove them (if 119 // When resized we may need to add new buttons, or remove them (if
109 // no longer visible), or add/remove the "off the side" menu. 120 // no longer visible), or add/remove the "off the side" menu.
110 [[self view] setPostsFrameChangedNotifications:YES]; 121 [[self view] setPostsFrameChangedNotifications:YES];
111 [[NSNotificationCenter defaultCenter] 122 [[NSNotificationCenter defaultCenter]
112 addObserver:self 123 addObserver:self
113 selector:@selector(frameDidChange) 124 selector:@selector(frameDidChange)
114 name:NSViewFrameDidChangeNotification 125 name:NSViewFrameDidChangeNotification
115 object:[self view]]; 126 object:[self view]];
116
117 DCHECK([offTheSideButton_ attachedMenu]);
118 } 127 }
119 128
120 // Method is the same as [self view], but is provided to be explicit. 129 // Method is the same as [self view], but is provided to be explicit.
121 - (BackgroundGradientView*)backgroundGradientView { 130 - (BackgroundGradientView*)backgroundGradientView {
122 return (BackgroundGradientView*)[self view]; 131 return (BackgroundGradientView*)[self view];
123 } 132 }
124 133
125 - (void)showIfNeeded { 134 - (void)showIfNeeded {
126 if (browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar)) 135 if (browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar))
127 [self showBookmarkBar:YES immediately:YES]; 136 [self showBookmarkBar:YES immediately:YES];
128 } 137 }
129 138
130 // Check if we should enable the off-the-side button. 139 // Position the off-the-side chevron to the left of the otherBookmarks button.
140 - (void)positionOffTheSideButton {
141 NSRect frame = [offTheSideButton_ frame];
142 frame.origin.x = ([otherBookmarksButton_ frame].origin.x -
143 (frame.size.width + bookmarks::kBookmarkHorizontalPadding));
144 [offTheSideButton_ setFrame:frame];
145 }
146
147 // Check if we should enable or disable the off-the-side chevron.
148 // Assumes that buttons which don't fit in the parent view are removed
149 // from it.
150 //
131 // TODO(jrg): when we are smarter about creating buttons (e.g. don't 151 // TODO(jrg): when we are smarter about creating buttons (e.g. don't
132 // bother creating buttons which aren't visible), we'll have to be 152 // bother creating buttons which aren't visible), we'll have to be
133 // smarter here too. 153 // smarter here too.
134 - (void)checkHideOffTheSideButton { 154 - (void)showOrHideOffTheSideButton {
155 // Then determine if we'll hide or show it.
135 NSButton* button = [buttons_ lastObject]; 156 NSButton* button = [buttons_ lastObject];
136 if ((!button) || 157 if (button && ![button superview]) {
137 (NSMaxX([button frame]) <= 158 [offTheSideButton_ setHidden:NO];
138 NSMaxX([[button superview] frame]))) { 159 } else {
139 [offTheSideButton_ setHidden:YES]; 160 [offTheSideButton_ setHidden:YES];
140 } else {
141 [offTheSideButton_ setHidden:NO];
142 } 161 }
143 } 162 }
144 163
145 - (BOOL)offTheSideButtonIsHidden { 164 - (BOOL)offTheSideButtonIsHidden {
146 return [offTheSideButton_ isHidden]; 165 return [offTheSideButton_ isHidden];
147 } 166 }
148 167
149 // Called when our controlled frame has changed size. 168 // Called when our controlled frame has changed size.
150 // TODO(jrg): be smarter (e.g. add/remove buttons as appropriate).
151 - (void)frameDidChange { 169 - (void)frameDidChange {
152 [self checkHideOffTheSideButton]; 170 [self resizeButtons];
171 [self positionOffTheSideButton];
172 [self addButtonsToView];
173 [self showOrHideOffTheSideButton];
174 [self centerNoItemsLabel];
175 }
153 176
154 // Need to keep the "no items" label centered. 177 // Keep the "no items" label centered in response to a frame size change.
178 - (void)centerNoItemsLabel {
155 NSView* noItemsView = [buttonView_ noItemTextfield]; 179 NSView* noItemsView = [buttonView_ noItemTextfield];
156 NSRect frame = [noItemsView frame]; 180 NSRect frame = [noItemsView frame];
157 NSRect parent = [buttonView_ bounds]; 181 NSRect parent = [buttonView_ bounds];
158 NSPoint newOrigin; 182 NSPoint newOrigin;
159 newOrigin.x = parent.origin.x + bookmarks::kNoBookmarksHorizontalOffset; 183 newOrigin.x = parent.origin.x + bookmarks::kNoBookmarksHorizontalOffset;
160 newOrigin.y = parent.origin.y + parent.size.height - 184 newOrigin.y = parent.origin.y + parent.size.height -
161 ([self isAlwaysVisible] ? bookmarks::kNoBookmarksVerticalOffset : 185 ([self isAlwaysVisible] ? bookmarks::kNoBookmarksVerticalOffset :
162 bookmarks::kNoBookmarksNTPVerticalOffset); 186 bookmarks::kNoBookmarksNTPVerticalOffset);
163 [noItemsView setFrameOrigin:newOrigin]; 187 [noItemsView setFrameOrigin:newOrigin];
164 } 188 }
165 189
190 // Change the layout of the bookmark bar's subviews in response to a
191 // visibility change (e.g. show or hide the bar) or style change
192 // (attached or floating).
193 - (void)layoutSubviews {
194 if ([self drawAsFloatingBar]) {
195 // The internal bookmark bar should have padding to center it.
196 NSRect frame = [[self view] frame];
197 [buttonView_ setFrame:
198 NSMakeRect(bookmarks::kNTPBookmarkBarPadding,
199 bookmarks::kNTPBookmarkBarPadding,
200 (NSWidth(frame) -
201 bookmarks::kNTPBookmarkBarPadding*2),
202 (NSHeight(frame) -
203 bookmarks::kNTPBookmarkBarPadding))];
204 } else {
205 // The frame of our child should be equal to our frame, excluding
206 // space for stuff on the right side (e.g. off-the-side chevron).
207 NSRect frame = [[self view] frame];
208 [buttonView_ setFrame:NSMakeRect(0, 0, NSWidth(frame), NSHeight(frame))];
209 }
210 }
211
166 // Show or hide the bar based on the value of |show|. Handles animating the 212 // Show or hide the bar based on the value of |show|. Handles animating the
167 // resize of the content view. if |immediately| is YES, make changes 213 // resize of the content view. if |immediately| is YES, make changes
168 // immediately instead of using an animator. The routine which enables the bar 214 // immediately instead of using an animator. The routine which enables the bar
169 // will show it if relevant using other mechanisms (the pref) to determine 215 // will show it if relevant using other mechanisms (the pref) to determine
170 // desired state. 216 // desired state.
171 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { 217 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately {
172 BOOL compressed = [self isAlwaysVisible]; 218 BOOL compressed = [self isAlwaysVisible];
173 [compressDelegate_ setShouldBeCompressed:compressed]; 219 [compressDelegate_ setShouldBeCompressed:compressed];
174 220
175 CGFloat height = show ? [self preferredHeight] : 0; 221 CGFloat height = show ? [self preferredHeight] : 0;
176 [resizeDelegate_ resizeView:[self view] newHeight:height]; 222 [resizeDelegate_ resizeView:[self view] newHeight:height];
177 [[self view] setHidden:show ? NO : YES]; 223 [[self view] setHidden:show ? NO : YES];
178 224
179 DCHECK([[self view] isKindOfClass:[BookmarkBarToolbarView class]]); 225 DCHECK([[self view] isKindOfClass:[BookmarkBarToolbarView class]]);
180 [(BookmarkBarToolbarView*)[self view] layoutViews]; 226 [self layoutSubviews];
227 [self frameDidChange];
181 } 228 }
182 229
183 // We don't change a preference; we only change visibility. 230 // We don't change a preference; we only change visibility.
184 // Preference changing (global state) is handled in 231 // Preference changing (global state) is handled in
185 // BrowserWindowCocoa::ToggleBookmarkBar(). We simply update the visibility of 232 // BrowserWindowCocoa::ToggleBookmarkBar(). We simply update the visibility of
186 // the bar based on the current value of the pref. 233 // the bar based on the current value of the pref.
187 - (void)updateVisibility { 234 - (void)updateVisibility {
188 [self showBookmarkBar:[self isVisible] immediately:YES]; 235 [self showBookmarkBar:[self isVisible] immediately:YES];
189 } 236 }
190 237
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // here. 434 // here.
388 - (void)buildOffTheSideMenu { 435 - (void)buildOffTheSideMenu {
389 NSMenu* menu = [self offTheSideMenu]; 436 NSMenu* menu = [self offTheSideMenu];
390 DCHECK(menu); 437 DCHECK(menu);
391 438
392 // Remove old menu items (backwards order is as good as any); leave the 439 // Remove old menu items (backwards order is as good as any); leave the
393 // blank one at position 0 (see menu_button.h). 440 // blank one at position 0 (see menu_button.h).
394 for (NSInteger i = [menu numberOfItems] - 1; i >= 1 ; i--) 441 for (NSInteger i = [menu numberOfItems] - 1; i >= 1 ; i--)
395 [menu removeItemAtIndex:i]; 442 [menu removeItemAtIndex:i];
396 443
397 // Add items corresponding to buttons which aren't displayed or are only 444 // Add items corresponding to buttons which aren't displayed.
398 // partly displayed. 445 for (NSButton* button in buttons_.get()) {
399 for (NSButton* each_button in buttons_.get()) { 446 if (![button superview])
400 if (NSMaxX([each_button frame]) > 447 [self addNode:[self nodeFromButton:button] toMenu:menu];
401 NSMaxX([[each_button superview] frame])) {
402 [self addNode:[self nodeFromButton:each_button] toMenu:menu];
403 }
404 } 448 }
405 } 449 }
406 450
407 // Get the off-the-side menu. 451 // Get the off-the-side menu.
408 - (NSMenu*)offTheSideMenu { 452 - (NSMenu*)offTheSideMenu {
409 return [offTheSideButton_ attachedMenu]; 453 return [offTheSideButton_ attachedMenu];
410 } 454 }
411 455
412 // Called by any menus which have set us as their delegate (right now just the 456 // Called by any menus which have set us as their delegate (right now just the
413 // off-the-side menu?). 457 // off-the-side menu?).
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 569
526 // runAsModalSheet will run the window as a sheet. The 570 // runAsModalSheet will run the window as a sheet. The
527 // BookmarkNameFolderController will release itself when the sheet 571 // BookmarkNameFolderController will release itself when the sheet
528 // ends. 572 // ends.
529 } 573 }
530 574
531 - (BookmarkBarView*)buttonView { 575 - (BookmarkBarView*)buttonView {
532 return buttonView_; 576 return buttonView_;
533 } 577 }
534 578
535 // Delete all bookmarks from the bookmark bar, and reset knowledge of 579 // Delete all buttons (bookmarks, chevron, "other bookmarks") from the
536 // bookmarks. 580 // bookmark bar; reset knowledge of bookmarks.
537 - (void)clearBookmarkBar { 581 - (void)clearBookmarkBar {
538 [buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)]; 582 [buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)];
539 [buttons_ removeAllObjects]; 583 [buttons_ removeAllObjects];
540 [self clearMenuTagMap]; 584 [self clearMenuTagMap];
541 } 585 }
542 586
543 // Return an autoreleased NSCell suitable for a bookmark button. 587 // Return an autoreleased NSCell suitable for a bookmark button.
544 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. 588 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class.
545 - (NSCell*)cellForBookmarkNode:(const BookmarkNode*)node { 589 - (NSCell*)cellForBookmarkNode:(const BookmarkNode*)node {
546 NSString* title = base::SysWideToNSString(node->GetTitle()); 590 NSString* title = base::SysWideToNSString(node->GetTitle());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 // offset for the frame; it is increased to be an appropriate X offset 626 // offset for the frame; it is increased to be an appropriate X offset
583 // for the next button. 627 // for the next button.
584 - (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell 628 - (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell
585 xOffset:(int*)xOffset { 629 xOffset:(int*)xOffset {
586 NSRect bounds = [buttonView_ bounds]; 630 NSRect bounds = [buttonView_ bounds];
587 // TODO(erg,jrg): There used to be an if statement here, comparing the height 631 // TODO(erg,jrg): There used to be an if statement here, comparing the height
588 // to 0. This essentially broke sizing because we're dealing with floats and 632 // to 0. This essentially broke sizing because we're dealing with floats and
589 // the height wasn't precisely zero. The previous author wrote that they were 633 // the height wasn't precisely zero. The previous author wrote that they were
590 // doing this because of an animator, but we are not doing animations for beta 634 // doing this because of an animator, but we are not doing animations for beta
591 // so we do not care. 635 // so we do not care.
592 bounds.size.height = bookmarks::kBookmarkBarHeight; 636 bounds.size.height = bookmarks::kBookmarkButtonHeight;
593 637
594 NSRect frame = NSInsetRect(bounds, 638 NSRect frame = NSInsetRect(bounds,
595 bookmarks::kBookmarkHorizontalPadding, 639 bookmarks::kBookmarkHorizontalPadding,
596 bookmarks::kBookmarkVerticalPadding); 640 bookmarks::kBookmarkVerticalPadding);
597 frame.size.width = [self widthForBookmarkButtonCell:cell]; 641 frame.size.width = [self widthForBookmarkButtonCell:cell];
598 642
599 // Add an X offset based on what we've already done 643 // Add an X offset based on what we've already done
600 frame.origin.x += *xOffset; 644 frame.origin.x += *xOffset;
601 645
602 // And up the X offset for next time. 646 // And up the X offset for next time.
603 *xOffset = NSMaxX(frame); 647 *xOffset = NSMaxX(frame);
604 648
605 return frame; 649 return frame;
606 } 650 }
607 651
608 // A bookmark button's contents changed. Check for growth 652 // A bookmark button's contents changed. Check for growth
609 // (e.g. increase the width up to the maximum). If we grew, move 653 // (e.g. increase the width up to the maximum). If we grew, move
610 // other bookmark buttons over. 654 // other bookmark buttons over.
611 - (void)checkForBookmarkButtonGrowth:(NSButton*)button { 655 - (void)checkForBookmarkButtonGrowth:(NSButton*)button {
612 NSRect frame = [button frame]; 656 NSRect frame = [button frame];
613 CGFloat desiredSize = [self widthForBookmarkButtonCell:[button cell]]; 657 CGFloat desiredSize = [self widthForBookmarkButtonCell:[button cell]];
614 CGFloat delta = desiredSize - frame.size.width; 658 CGFloat delta = desiredSize - frame.size.width;
615 if (delta) { 659 if (delta) {
616 frame.size.width = desiredSize; 660 frame.size.width = desiredSize;
617 [button setFrame:frame]; 661 [button setFrame:frame];
618 for (NSButton* each_button in buttons_.get()) { 662 for (NSButton* button in buttons_.get()) {
619 NSRect each_frame = [each_button frame]; 663 NSRect buttonFrame = [button frame];
620 if (each_frame.origin.x > frame.origin.x) { 664 if (buttonFrame.origin.x > frame.origin.x) {
621 each_frame.origin.x += delta; 665 buttonFrame.origin.x += delta;
622 [each_button setFrame:each_frame]; 666 [button setFrame:buttonFrame];
623 } 667 }
624 } 668 }
625 } 669 }
626 // We may have just crossed a threshold to enable the off-the-side 670 // We may have just crossed a threshold to enable the off-the-side
627 // button. 671 // button.
628 [self checkHideOffTheSideButton]; 672 [self showOrHideOffTheSideButton];
629 } 673 }
630 674
631 - (IBAction)openBookmarkMenuItem:(id)sender { 675 - (IBAction)openBookmarkMenuItem:(id)sender {
632 int64 tag = [self nodeIdFromMenuTag:[sender tag]]; 676 int64 tag = [self nodeIdFromMenuTag:[sender tag]];
633 const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag); 677 const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag);
634 WindowOpenDisposition disposition = 678 WindowOpenDisposition disposition =
635 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); 679 event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
636 [urlDelegate_ openBookmarkURL:node->GetURL() disposition:disposition]; 680 [urlDelegate_ openBookmarkURL:node->GetURL() disposition:disposition];
637 } 681 }
638 682
639 // Add all items from the given model to our bookmark bar. 683 // Create buttons for all items in the bookmark node tree.
640 // 684 //
641 // TODO(jrg): write a "build bar" so there is a nice spot for things 685 // TODO(jrg): write a "build bar" so there is a nice spot for things
642 // like the contextual menu which is invoked when not over a 686 // like the contextual menu which is invoked when not over a
643 // bookmark. On Safari that menu has a "new folder" option. 687 // bookmark. On Safari that menu has a "new folder" option.
644 - (void)addNodesToBar:(const BookmarkNode*)node { 688 - (void)addNodesToButtonList:(const BookmarkNode*)node {
645 BOOL hidden = (node->GetChildCount() == 0) ? NO : YES; 689 BOOL hidden = (node->GetChildCount() == 0) ? NO : YES;
646 NSView* item = [buttonView_ noItemTextfield]; 690 NSView* item = [buttonView_ noItemTextfield];
647 [item setHidden:hidden]; 691 [item setHidden:hidden];
648 692
649 int x_offset = 0; 693 int xOffset = 0;
650 for (int i = 0; i < node->GetChildCount(); i++) { 694 for (int i = 0; i < node->GetChildCount(); i++) {
651 const BookmarkNode* child = node->GetChild(i); 695 const BookmarkNode* child = node->GetChild(i);
652 696
653 NSCell* cell = [self cellForBookmarkNode:child]; 697 NSCell* cell = [self cellForBookmarkNode:child];
654 NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:&x_offset]; 698 NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:&xOffset];
655 NSButton* button = [[[BookmarkButton alloc] initWithFrame:frame] 699 NSButton* button = [[[BookmarkButton alloc] initWithFrame:frame]
656 autorelease]; 700 autorelease];
657 DCHECK(button); 701 DCHECK(button);
658 [buttons_ addObject:button]; 702 [buttons_ addObject:button];
659 703
660 // [NSButton setCell:] warns to NOT use setCell: other than in the 704 // [NSButton setCell:] warns to NOT use setCell: other than in the
661 // initializer of a control. However, we are using a basic 705 // initializer of a control. However, we are using a basic
662 // NSButton whose initializer does not take an NSCell as an 706 // NSButton whose initializer does not take an NSCell as an
663 // object. To honor the assumed semantics, we do nothing with 707 // object. To honor the assumed semantics, we do nothing with
664 // NSButton between alloc/init and setCell:. 708 // NSButton between alloc/init and setCell:.
665 [button setCell:cell]; 709 [button setCell:cell];
666 710
667 if (child->is_folder()) { 711 if (child->is_folder()) {
668 [button setTarget:self]; 712 [button setTarget:self];
669 [button setAction:@selector(openFolderMenuFromButton:)]; 713 [button setAction:@selector(openFolderMenuFromButton:)];
670 } else { 714 } else {
671 // Make the button do something 715 // Make the button do something
672 [button setTarget:self]; 716 [button setTarget:self];
673 [button setAction:@selector(openBookmark:)]; 717 [button setAction:@selector(openBookmark:)];
674 // Add a tooltip. 718 // Add a tooltip.
675 NSString* title = base::SysWideToNSString(child->GetTitle()); 719 NSString* title = base::SysWideToNSString(child->GetTitle());
676 std::string url_string = child->GetURL().possibly_invalid_spec(); 720 std::string url_string = child->GetURL().possibly_invalid_spec();
677 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title, 721 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title,
678 url_string.c_str()]; 722 url_string.c_str()];
679 [button setToolTip:tooltip]; 723 [button setToolTip:tooltip];
680 } 724 }
681 // Finally, add it to the bookmark bar.
682 [buttonView_ addSubview:button];
683 } 725 }
684 } 726 }
685 727
728 // Add non-bookmark buttons to the view. This includes the chevron
729 // and the "other bookmarks" button. Technically "other bookmarks" is
730 // a bookmark button but it is treated specially. Only needs to be
731 // called when these buttons are new or when the bookmark bar is
732 // cleared (e.g. on a loaded: call). Unlike addButtonsToView below,
733 // we don't need to add/remove these dynamically in response to window
734 // resize.
735 - (void)addNonBookmarkButtonsToView {
736 [buttonView_ addSubview:otherBookmarksButton_.get()];
737 [buttonView_ addSubview:offTheSideButton_];
738 }
739
740 // Add bookmark buttons to the view only if they are completely
741 // visible and don't overlap the "other bookmarks". Remove buttons
742 // which are clipped. Called when building the bookmark bar and when
743 // the window resizes.
744 - (void)addButtonsToView {
745 NSView* superview = nil;
746 for (NSButton* button in buttons_.get()) {
747 superview = [button superview];
748 if (NSMaxX([button frame]) <= NSMinX([offTheSideButton_ frame])) {
749 if (!superview)
750 [buttonView_ addSubview:button];
751 } else {
752 if (superview)
753 [button removeFromSuperview];
754 }
755 }
756 }
757
758 // Helper for resizeButtons to resize buttons based on a new parent
759 // view height.
760 - (void)resizeButtonsInArray:(NSArray*)array {
761 NSRect parentBounds = [buttonView_ bounds];
762 CGFloat height = (bookmarks::kBookmarkButtonHeight -
763 (bookmarks::kBookmarkVerticalPadding*2));
764 for (NSButton* button in array) {
765 NSRect frame = [button frame];
766 frame.size.height = height;
767 [button setFrame:frame];
768 }
769 }
770
771 // Resize our buttons; the parent view height may have changed. This
772 // applies to all bookmarks, the chevron, and the "Other Bookmarks"
773 - (void)resizeButtons {
774 [self resizeButtonsInArray:buttons_.get()];
775 NSMutableArray* array = [NSMutableArray arrayWithObject:offTheSideButton_];
776 // We must handle resize before the bookmarks are loaded. If not loaded,
777 // we have no otherBookmarksButton_ yet.
778 if (otherBookmarksButton_.get())
779 [array addObject:otherBookmarksButton_.get()];
780 [self resizeButtonsInArray:array];
781 }
782
783 // Create the button for "Other Bookmarks" on the right of the bar.
784 - (void)createOtherBookmarksButton {
785 // Can't create this until the model is loaded, but only need to
786 // create it once.
787 if (otherBookmarksButton_.get())
788 return;
789
790 // TODO(jrg): remove duplicate code
791 NSCell* cell = [self cellForBookmarkNode:bookmarkModel_->other_node()];
792 int ignored = 0;
793 NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:&ignored];
794 frame.origin.x = [[self buttonView] bounds].size.width - frame.size.width;
795 frame.origin.x -= bookmarks::kBookmarkHorizontalPadding;
796 NSButton* button = [[BookmarkButton alloc] initWithFrame:frame];
797 otherBookmarksButton_.reset(button);
798
799 // Peg at right; keep same height as bar.
800 [button setAutoresizingMask:(NSViewMinXMargin)];
801 [button setCell:cell];
802 [button setTarget:self];
803 [button setAction:@selector(openFolderMenuFromButton:)];
804 [buttonView_ addSubview:button];
805
806 // Now that it's here, move the chevron over.
807 NSRect oframe = [offTheSideButton_ frame];
808 oframe.origin.x = frame.origin.x - (oframe.size.width +
809 bookmarks::kBookmarkHorizontalPadding);
810
811 // Force it to be the right size, right now.
812 [self resizeButtons];
813 }
814
686 // TODO(jrg): for now this is brute force. 815 // TODO(jrg): for now this is brute force.
687 - (void)loaded:(BookmarkModel*)model { 816 - (void)loaded:(BookmarkModel*)model {
688 DCHECK(model == bookmarkModel_); 817 DCHECK(model == bookmarkModel_);
689 if (!model->IsLoaded()) 818 if (!model->IsLoaded())
690 return; 819 return;
691 // Else brute force nuke and build. 820 // Else brute force nuke and build.
692 const BookmarkNode* node = model->GetBookmarkBarNode(); 821 const BookmarkNode* node = model->GetBookmarkBarNode();
693 [self clearBookmarkBar]; 822 [self clearBookmarkBar];
694 [self addNodesToBar:node]; 823 [self addNodesToButtonList:node];
695 [self checkHideOffTheSideButton]; 824 [self createOtherBookmarksButton];
825 [self resizeButtons];
826 [self positionOffTheSideButton];
827 [self addNonBookmarkButtonsToView];
828 [self addButtonsToView];
829 [self showOrHideOffTheSideButton];
696 } 830 }
697 831
698 - (void)beingDeleted:(BookmarkModel*)model { 832 - (void)beingDeleted:(BookmarkModel*)model {
699 [self clearBookmarkBar]; 833 [self clearBookmarkBar];
700 } 834 }
701 835
702 // TODO(jrg): for now this is brute force. 836 // TODO(jrg): for now this is brute force.
703 - (void)nodeMoved:(BookmarkModel*)model 837 - (void)nodeMoved:(BookmarkModel*)model
704 oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex 838 oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
705 newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex { 839 newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 } 894 }
761 895
762 - (void)setUrlDelegate:(id<BookmarkURLOpener>)urlDelegate { 896 - (void)setUrlDelegate:(id<BookmarkURLOpener>)urlDelegate {
763 urlDelegate_ = urlDelegate; 897 urlDelegate_ = urlDelegate;
764 } 898 }
765 899
766 - (NSArray*)buttons { 900 - (NSArray*)buttons {
767 return buttons_.get(); 901 return buttons_.get();
768 } 902 }
769 903
904 - (NSButton*)offTheSideButton {
905 return offTheSideButton_;
906 }
907
908 - (NSButton*)otherBookmarksButton {
909 return otherBookmarksButton_.get();
910 }
911
770 @end 912 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/bookmark_bar_controller.h ('k') | chrome/browser/cocoa/bookmark_bar_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698