OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |