| Index: chrome/browser/cocoa/extensions/browser_actions_controller.mm
|
| ===================================================================
|
| --- chrome/browser/cocoa/extensions/browser_actions_controller.mm (revision 42818)
|
| +++ chrome/browser/cocoa/extensions/browser_actions_controller.mm (working copy)
|
| @@ -4,6 +4,7 @@
|
|
|
| #import "browser_actions_controller.h"
|
|
|
| +#include <cmath>
|
| #include <string>
|
|
|
| #include "app/resource_bundle.h"
|
| @@ -59,7 +60,7 @@
|
| // Useful in the case of a Browser Action being added/removed from the middle of
|
| // the container, this method repositions each button according to the current
|
| // toolbar model.
|
| -- (void)repositionActionButtons;
|
| +- (void)repositionActionButtonsAndAnimate:(BOOL)animate;
|
| // During container resizing, buttons become more transparent as they are pushed
|
| // off the screen. This method updates each button's opacity determined by the
|
| // position of the button.
|
| @@ -90,7 +91,17 @@
|
| // Updates the image associated with the button should it be within the chevron
|
| // menu.
|
| - (void)actionButtonUpdated:(NSNotification*)notification;
|
| -
|
| +// Adjusts the position of the surrounding action buttons depending on where the
|
| +// button is within the container.
|
| +- (void)actionButtonDragging:(NSNotification*)notification;
|
| +// Updates the underlying toolbar model and "snaps" the button into its proper
|
| +// place within the button grid.
|
| +- (void)actionButtonDragFinished:(NSNotification*)notification;
|
| +// Moves the given button both visually and within the toolbar model to the
|
| +// specified index.
|
| +- (void)moveButton:(BrowserActionButton*)button
|
| + toIndex:(NSUInteger)index
|
| + animate:(BOOL)animate;
|
| // Handles when the given BrowserActionButton object is clicked.
|
| - (void)browserActionClicked:(BrowserActionButton*)button;
|
| // Returns whether the given extension should be displayed. Only displays
|
| @@ -424,7 +435,18 @@
|
| [self updateOverflowMenu];
|
| }
|
|
|
| - [self repositionActionButtons];
|
| + [[NSNotificationCenter defaultCenter]
|
| + addObserver:self
|
| + selector:@selector(actionButtonDragging:)
|
| + name:kBrowserActionButtonDraggingNotification
|
| + object:newButton];
|
| + [[NSNotificationCenter defaultCenter]
|
| + addObserver:self
|
| + selector:@selector(actionButtonDragFinished:)
|
| + name:kBrowserActionButtonDragEndNotification
|
| + object:newButton];
|
| +
|
| + [self repositionActionButtonsAndAnimate:NO];
|
| [containerView_ setMaxWidth:
|
| [self containerWidthWithButtonCount:[self buttonCount]]];
|
| [containerView_ setNeedsDisplay:YES];
|
| @@ -455,28 +477,24 @@
|
| // No more buttons? Hide the container.
|
| [containerView_ setHidden:YES];
|
| } else {
|
| - [self repositionActionButtons];
|
| + [self repositionActionButtonsAndAnimate:NO];
|
| }
|
| [containerView_ setMaxWidth:
|
| [self containerWidthWithButtonCount:[self buttonCount]]];
|
| [containerView_ setNeedsDisplay:YES];
|
| }
|
|
|
| -- (void)repositionActionButtons {
|
| +- (void)repositionActionButtonsAndAnimate:(BOOL)animate {
|
| NSUInteger i = 0;
|
| for (ExtensionList::iterator iter = toolbarModel_->begin();
|
| iter != toolbarModel_->end(); ++iter) {
|
| if (![self shouldDisplayBrowserAction:*iter])
|
| continue;
|
| -
|
| - CGFloat xOffset = kGrippyXOffset +
|
| - (i * (kBrowserActionWidth + kBrowserActionButtonPadding));
|
| BrowserActionButton* button = [self buttonForExtension:(*iter)];
|
| if (!button)
|
| continue;
|
| - NSRect buttonFrame = [button frame];
|
| - buttonFrame.origin.x = xOffset;
|
| - [button setFrame:buttonFrame];
|
| + if (![button isBeingDragged])
|
| + [self moveButton:button toIndex:i animate:animate];
|
| ++i;
|
| }
|
| }
|
| @@ -587,6 +605,49 @@
|
| [item setImage:[button compositedImage]];
|
| }
|
|
|
| +- (void)actionButtonDragging:(NSNotification*)notification {
|
| + if (![self chevronIsHidden])
|
| + [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES];
|
| +
|
| + // Determine what index the dragged button should lie in, alter the model and
|
| + // reposition the buttons.
|
| + CGFloat dragThreshold = std::floor(kBrowserActionWidth / 2);
|
| + BrowserActionButton* draggedButton = [notification object];
|
| + NSRect draggedButtonFrame = [draggedButton frame];
|
| +
|
| + NSUInteger index = 0;
|
| + for (ExtensionList::iterator iter = toolbarModel_->begin();
|
| + iter != toolbarModel_->end(); ++iter) {
|
| + BrowserActionButton* button = [self buttonForExtension:(*iter)];
|
| + CGFloat intersectionWidth =
|
| + NSWidth(NSIntersectionRect(draggedButtonFrame, [button frame]));
|
| +
|
| + if (intersectionWidth > dragThreshold && button != draggedButton &&
|
| + ![button isAnimating]) {
|
| + toolbarModel_->MoveBrowserAction([draggedButton extension], index);
|
| + [self repositionActionButtonsAndAnimate:YES];
|
| + return;
|
| + }
|
| + ++index;
|
| + }
|
| +}
|
| +
|
| +- (void)actionButtonDragFinished:(NSNotification*)notification {
|
| + [self showChevronIfNecessaryInFrame:[containerView_ frame] animate:YES];
|
| + DCHECK(![[notification object] isBeingDragged]);
|
| + [self repositionActionButtonsAndAnimate:YES];
|
| +}
|
| +
|
| +- (void)moveButton:(BrowserActionButton*)button
|
| + toIndex:(NSUInteger)index
|
| + animate:(BOOL)animate {
|
| + CGFloat xOffset = kGrippyXOffset +
|
| + (index * (kBrowserActionWidth + kBrowserActionButtonPadding));
|
| + NSRect buttonFrame = [button frame];
|
| + buttonFrame.origin.x = xOffset;
|
| + [button setFrame:buttonFrame animate:animate];
|
| +}
|
| +
|
| - (void)browserActionClicked:(BrowserActionButton*)button {
|
| int tabId = [self currentTabId];
|
| if (tabId < 0) {
|
| @@ -669,7 +730,7 @@
|
| nil];
|
| }
|
| [chevronAnimation_ setViewAnimations:
|
| - [NSArray arrayWithObjects:animationDictionary, nil]];
|
| + [NSArray arrayWithObject:animationDictionary]];
|
| [chevronAnimation_ startAnimation];
|
| }
|
|
|
|
|