diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 22:02:49 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 22:02:49 +0000 |
commit | 324ad2f3d320abff71801dd3b4af2ff02100da40 (patch) | |
tree | ce61a71c7d20ce630e0f3984b6c0809b0085c4f2 /chrome/browser/cocoa/bookmark_bar_controller.mm | |
parent | c8f67b0d6ceb690fbf02f15777356fbe03af9ac2 (diff) | |
download | chromium_src-324ad2f3d320abff71801dd3b4af2ff02100da40.zip chromium_src-324ad2f3d320abff71801dd3b4af2ff02100da40.tar.gz chromium_src-324ad2f3d320abff71801dd3b4af2ff02100da40.tar.bz2 |
Make the "off the side" menu (chevron) behave like the other bookmark
bar folders. E.g. supports DragAndDrop.
BUG=34910
TEST=Make sure you can DnD items to/from the "off the side" chevron.
Make sure context menus on those buttons work as well (e.g. delete).
Make sure the chevron is NOT draggable.
Make sure the chevron works properly as a "hover open" button when
dragging something else around; e.g. it pops open if you hover over
it. (It's small so this may take patience).
Drop a folder from the bar into itself. Make sure we don't crash.
xib change:
- chevron button is now BookmarkButton, not MenuButton.
Also has BookmarkButtonCell in it.
- "off the side" menu removed.
Review URL: http://codereview.chromium.org/1520003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43263 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/bookmark_bar_controller.mm')
-rw-r--r-- | chrome/browser/cocoa/bookmark_bar_controller.mm | 102 |
1 files changed, 43 insertions, 59 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index dfffd10..8a6d035 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -295,11 +295,12 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12; // expects. We will resize ourselves open later if needed. [[self view] setFrame:NSMakeRect(0, 0, initialWidth_, 0)]; + // Complete init of the "off the side" button, as much as we can. + [offTheSideButton_ setDraggable:NO]; + // We are enabled by default. barIsEnabled_ = YES; - DCHECK([offTheSideButton_ attachedMenu]); - // To make life happier when the bookmark bar is floating, the chevron is a // child of the button view. [offTheSideButton_ removeFromSuperview]; @@ -376,10 +377,12 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12; } } -// Check if we should enable or disable the off-the-side chevron. -// Assumes that buttons which don't fit in the parent view are removed -// from it. -- (void)showOrHideOffTheSideButton { +// Configure the off-the-side button (e.g. specify the node range, +// check if we should enable or disable it, etc). +- (void)configureOffTheSideButtonContentsAndVisibility { + [[offTheSideButton_ cell] setStartingChildIndex:bookmarkBarDisplayedButtons_]; + [[offTheSideButton_ cell] + setBookmarkNode:bookmarkModel_->GetBookmarkBarNode()]; int bookmarkChildren = bookmarkModel_->GetBookmarkBarNode()->GetChildCount(); if (bookmarkChildren > bookmarkBarDisplayedButtons_) { [offTheSideButton_ setHidden:NO]; @@ -406,7 +409,7 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12; } [self positionOffTheSideButton]; [self addButtonsToView]; - [self showOrHideOffTheSideButton]; + [self configureOffTheSideButtonContentsAndVisibility]; [self centerNoItemsLabel]; } @@ -745,11 +748,13 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12; const BookmarkNode* afterNode = [buttonToTheRightOfDraggedButton bookmarkNode]; DCHECK(afterNode); - return afterNode->GetParent()->IndexOfChild(afterNode); + int index = afterNode->GetParent()->IndexOfChild(afterNode); + // Make sure we don't get confused by buttons which aren't visible. + return std::min(index, bookmarkBarDisplayedButtons_); } // If nothing is to my right I am at the end! - return [buttons_ count]; + return bookmarkBarDisplayedButtons_; } - (BOOL)dragButton:(BookmarkButton*)sourceButton @@ -777,10 +782,14 @@ const NSTimeInterval kBookmarkBarAnimationDuration = 0.12; destIndex = [self indexForDragOfButton:sourceButton toPoint:point]; } - if (copy) - bookmarkModel_->Copy(sourceNode, destParent, destIndex); - else - bookmarkModel_->Move(sourceNode, destParent, destIndex); + // Be sure we don't try and drop a folder into itself. + if (sourceNode != destParent) { + if (copy) { + bookmarkModel_->Copy(sourceNode, destParent, destIndex); + } else { + bookmarkModel_->Move(sourceNode, destParent, destIndex); + } + } [self closeAllBookmarkFolders]; // For a hover open, if needed. @@ -805,7 +814,8 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { fromArray:(NSArray*)array { for (BookmarkButton* button in array) { // Break early if we've gone too far. - if (NSMinX([button frame]) > point.x) + if ((NSMinX([button frame]) > point.x) || + (![button superview])) return nil; // Careful -- this only applies to the bar with horiz buttons. // Intentionally NOT using NSPointInRect() so that scrolling into @@ -814,7 +824,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { point.x, NSMaxX([button frame]))) { // Over a button but let's be a little more specific (make sure - // it's over the middle half, not just over it.) + // it's over the middle half, not just over it). NSRect frame = [button frame]; NSRect middleHalfOfButton = NSInsetRect(frame, frame.size.width / 4, 0); if (ValueInRangeInclusive(NSMinX(middleHalfOfButton), @@ -841,10 +851,13 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { - (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point { BookmarkButton* button = [self buttonForDroppingOnAtPoint:point fromArray:buttons_.get()]; - // One more chance -- try "Other Bookmarks". + // One more chance -- try "Other Bookmarks" and "off the side" (if visible). // This is different than BookmarkBarFolderController. if (!button) { - NSArray* array = [NSArray arrayWithObject:otherBookmarksButton_]; + NSMutableArray* array = [NSMutableArray array]; + if (![self offTheSideButtonIsHidden]) + [array addObject:offTheSideButton_]; + [array addObject:otherBookmarksButton_]; button = [self buttonForDroppingOnAtPoint:point fromArray:array]; } @@ -911,7 +924,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { toPoint:(NSPoint)point { CGFloat x = 0; int destIndex = [self indexForDragOfButton:sourceButton toPoint:point]; - int numButtons = static_cast<int>([buttons_ count]); + int numButtons = bookmarkBarDisplayedButtons_; // If it's a drop strictly between existing buttons ... if (destIndex >= 0 && destIndex < numButtons) { @@ -1105,6 +1118,16 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [folderTarget_ openBookmarkFolderFromButton:sender]; } +// The button that sends this one is special; the "off the side" +// button (chevron) opens like a folder button but isn't exactly a +// parent folder. +- (IBAction)openOffTheSideFolderFromButton:(id)sender { + DCHECK([sender isKindOfClass:[BookmarkButton class]]); + DCHECK([[sender cell] isKindOfClass:[BookmarkButtonCell class]]); + [[sender cell] setStartingChildIndex:bookmarkBarDisplayedButtons_]; + [folderTarget_ openBookmarkFolderFromButton:sender]; +} + // Recursively add the given bookmark node and all its children to // menu, one menu item per node. - (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu { @@ -1185,45 +1208,6 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [self watchForClickOutside:YES]; } -// Rebuild the off-the-side menu. -- (void)buildOffTheSideMenuIfNeeded { - NSMenu* menu = [self offTheSideMenu]; - DCHECK(menu); - - // Only rebuild if needed. We determine we need a rebuild when the - // bookmark bar is cleared of buttons. - if (!needToRebuildOffTheSideMenu_) - return; - needToRebuildOffTheSideMenu_ = YES; - - // Remove old menu items (backwards order is as good as any); leave the - // blank one at position 0 (see menu_button.h). - for (NSInteger i = [menu numberOfItems] - 1; i >= 1 ; i--) - [menu removeItemAtIndex:i]; - - // Add items corresponding to buttons which aren't displayed. Since - // we build the buttons in the same order as the bookmark bar child - // count, we have a clear hint as to where to begin. - const BookmarkNode* barNode = bookmarkModel_->GetBookmarkBarNode(); - for (int i = bookmarkBarDisplayedButtons_; - i < barNode->GetChildCount(); i++) { - const BookmarkNode* child = barNode->GetChild(i); - [self addNode:child toMenu:menu]; - } -} - -// Get the off-the-side menu. -- (NSMenu*)offTheSideMenu { - return [offTheSideButton_ attachedMenu]; -} - -// Called by any menus which have set us as their delegate (right now just the -// off-the-side menu). This is the trigger for a delayed rebuild. -- (void)menuNeedsUpdate:(NSMenu*)menu { - if (menu == [self offTheSideMenu]) - [self buildOffTheSideMenuIfNeeded]; -} - // As a convention we set the menu's delegate to be the button's cell // so we can easily obtain bookmark info. Convention applied in // -[BookmarkButtonCell menu]. @@ -1507,7 +1491,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } // We may have just crossed a threshold to enable the off-the-side // button. - [self showOrHideOffTheSideButton]; + [self configureOffTheSideButtonContentsAndVisibility]; } - (IBAction)openBookmarkMenuItem:(id)sender { @@ -1643,7 +1627,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [self positionOffTheSideButton]; [self addNonBookmarkButtonsToView]; [self addButtonsToView]; - [self showOrHideOffTheSideButton]; + [self configureOffTheSideButtonContentsAndVisibility]; [self setNodeForBarMenu]; } |