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

Side by Side Diff: chrome/browser/cocoa/extensions/browser_actions_controller.mm

Issue 1418003: [Mac] Enables drag N' drop for the buttons within the Browser Actions contain... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 months 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "browser_actions_controller.h" 5 #import "browser_actions_controller.h"
6 6
7 #include <cmath>
7 #include <string> 8 #include <string>
8 9
9 #include "app/resource_bundle.h" 10 #include "app/resource_bundle.h"
10 #include "base/sys_string_conversions.h" 11 #include "base/sys_string_conversions.h"
11 #include "chrome/browser/browser.h" 12 #include "chrome/browser/browser.h"
12 #include "chrome/browser/pref_service.h" 13 #include "chrome/browser/pref_service.h"
13 #import "chrome/browser/cocoa/extensions/browser_action_button.h" 14 #import "chrome/browser/cocoa/extensions/browser_action_button.h"
14 #import "chrome/browser/cocoa/extensions/browser_actions_container_view.h" 15 #import "chrome/browser/cocoa/extensions/browser_actions_container_view.h"
15 #import "chrome/browser/cocoa/extensions/extension_popup_controller.h" 16 #import "chrome/browser/cocoa/extensions/extension_popup_controller.h"
16 #import "chrome/browser/cocoa/menu_button.h" 17 #import "chrome/browser/cocoa/menu_button.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 // object since it is called when the toolbar model changes. 53 // object since it is called when the toolbar model changes.
53 - (void)createActionButtonForExtension:(Extension*)extension 54 - (void)createActionButtonForExtension:(Extension*)extension
54 withIndex:(NSUInteger)index; 55 withIndex:(NSUInteger)index;
55 // Removes an action button for the given extension from the container. This 56 // Removes an action button for the given extension from the container. This
56 // method also does not affect the underlying toolbar model since it is called 57 // method also does not affect the underlying toolbar model since it is called
57 // when the toolbar model changes. 58 // when the toolbar model changes.
58 - (void)removeActionButtonForExtension:(Extension*)extension; 59 - (void)removeActionButtonForExtension:(Extension*)extension;
59 // Useful in the case of a Browser Action being added/removed from the middle of 60 // Useful in the case of a Browser Action being added/removed from the middle of
60 // the container, this method repositions each button according to the current 61 // the container, this method repositions each button according to the current
61 // toolbar model. 62 // toolbar model.
62 - (void)repositionActionButtons; 63 - (void)repositionActionButtonsAndAnimate:(BOOL)animate;
63 // During container resizing, buttons become more transparent as they are pushed 64 // During container resizing, buttons become more transparent as they are pushed
64 // off the screen. This method updates each button's opacity determined by the 65 // off the screen. This method updates each button's opacity determined by the
65 // position of the button. 66 // position of the button.
66 - (void)updateButtonOpacity; 67 - (void)updateButtonOpacity;
67 // Returns the existing button with the given extension backing it; nil if it 68 // Returns the existing button with the given extension backing it; nil if it
68 // cannot be found or the extension's ID is invalid. 69 // cannot be found or the extension's ID is invalid.
69 - (BrowserActionButton*)buttonForExtension:(Extension*)extension; 70 - (BrowserActionButton*)buttonForExtension:(Extension*)extension;
70 // Returns the preferred width of the container given the number of visible 71 // Returns the preferred width of the container given the number of visible
71 // buttons |buttonCount|. 72 // buttons |buttonCount|.
72 - (CGFloat)containerWidthWithButtonCount:(NSUInteger)buttonCount; 73 - (CGFloat)containerWidthWithButtonCount:(NSUInteger)buttonCount;
(...skipping 10 matching lines...) Expand all
83 - (void)containerDragStart:(NSNotification*)notification; 84 - (void)containerDragStart:(NSNotification*)notification;
84 // Sends a notification for the toolbar to reposition surrounding UI elements. 85 // Sends a notification for the toolbar to reposition surrounding UI elements.
85 - (void)containerDragging:(NSNotification*)notification; 86 - (void)containerDragging:(NSNotification*)notification;
86 // Determines which buttons need to be hidden based on the new size, hides them 87 // Determines which buttons need to be hidden based on the new size, hides them
87 // and updates the chevron overflow menu. Also fires a notification to let the 88 // and updates the chevron overflow menu. Also fires a notification to let the
88 // toolbar know that the drag has finished. 89 // toolbar know that the drag has finished.
89 - (void)containerDragFinished:(NSNotification*)notification; 90 - (void)containerDragFinished:(NSNotification*)notification;
90 // Updates the image associated with the button should it be within the chevron 91 // Updates the image associated with the button should it be within the chevron
91 // menu. 92 // menu.
92 - (void)actionButtonUpdated:(NSNotification*)notification; 93 - (void)actionButtonUpdated:(NSNotification*)notification;
93 94 // Adjusts the position of the surrounding action buttons depending on where the
95 // button is within the container.
96 - (void)actionButtonDragging:(NSNotification*)notification;
97 // Updates the underlying toolbar model and "snaps" the button into its proper
98 // place within the button grid.
99 - (void)actionButtonDragFinished:(NSNotification*)notification;
100 // Moves the given button both visually and within the toolbar model to the
101 // specified index.
102 - (void)moveButton:(BrowserActionButton*)button
103 toIndex:(NSUInteger)index
104 animate:(BOOL)animate;
94 // Handles when the given BrowserActionButton object is clicked. 105 // Handles when the given BrowserActionButton object is clicked.
95 - (void)browserActionClicked:(BrowserActionButton*)button; 106 - (void)browserActionClicked:(BrowserActionButton*)button;
96 // Returns whether the given extension should be displayed. Only displays 107 // Returns whether the given extension should be displayed. Only displays
97 // incognito-enabled extensions in incognito mode. Otherwise returns YES. 108 // incognito-enabled extensions in incognito mode. Otherwise returns YES.
98 - (BOOL)shouldDisplayBrowserAction:(Extension*)extension; 109 - (BOOL)shouldDisplayBrowserAction:(Extension*)extension;
99 110
100 // The reason |frame| is specified in these chevron functions is because the 111 // The reason |frame| is specified in these chevron functions is because the
101 // container may be animating and the end frame of the animation should be 112 // container may be animating and the end frame of the animation should be
102 // passed instead of the current frame (which may be off and cause the chevron 113 // passed instead of the current frame (which may be off and cause the chevron
103 // to jump at the end of its animation). 114 // to jump at the end of its animation).
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 428
418 [buttons_ setObject:newButton forKey:buttonKey]; 429 [buttons_ setObject:newButton forKey:buttonKey];
419 if (index < [self containerButtonCapacity]) { 430 if (index < [self containerButtonCapacity]) {
420 [containerView_ addSubview:newButton]; 431 [containerView_ addSubview:newButton];
421 } else { 432 } else {
422 [hiddenButtons_ addObject:newButton]; 433 [hiddenButtons_ addObject:newButton];
423 [newButton setAlphaValue:0.0]; 434 [newButton setAlphaValue:0.0];
424 [self updateOverflowMenu]; 435 [self updateOverflowMenu];
425 } 436 }
426 437
427 [self repositionActionButtons]; 438 [[NSNotificationCenter defaultCenter]
439 addObserver:self
440 selector:@selector(actionButtonDragging:)
441 name:kBrowserActionButtonDraggingNotification
442 object:newButton];
443 [[NSNotificationCenter defaultCenter]
444 addObserver:self
445 selector:@selector(actionButtonDragFinished:)
446 name:kBrowserActionButtonDragEndNotification
447 object:newButton];
448
449 [self repositionActionButtonsAndAnimate:NO];
428 [containerView_ setMaxWidth: 450 [containerView_ setMaxWidth:
429 [self containerWidthWithButtonCount:[self buttonCount]]]; 451 [self containerWidthWithButtonCount:[self buttonCount]]];
430 [containerView_ setNeedsDisplay:YES]; 452 [containerView_ setNeedsDisplay:YES];
431 } 453 }
432 454
433 - (void)removeActionButtonForExtension:(Extension*)extension { 455 - (void)removeActionButtonForExtension:(Extension*)extension {
434 if (!extension->browser_action()) 456 if (!extension->browser_action())
435 return; 457 return;
436 458
437 NSString* buttonKey = base::SysUTF8ToNSString(extension->id()); 459 NSString* buttonKey = base::SysUTF8ToNSString(extension->id());
(...skipping 10 matching lines...) Expand all
448 // It may or may not be hidden, but it won't matter to NSMutableArray either 470 // It may or may not be hidden, but it won't matter to NSMutableArray either
449 // way. 471 // way.
450 [hiddenButtons_ removeObject:button]; 472 [hiddenButtons_ removeObject:button];
451 [self updateOverflowMenu]; 473 [self updateOverflowMenu];
452 474
453 [buttons_ removeObjectForKey:buttonKey]; 475 [buttons_ removeObjectForKey:buttonKey];
454 if ([self buttonCount] == 0) { 476 if ([self buttonCount] == 0) {
455 // No more buttons? Hide the container. 477 // No more buttons? Hide the container.
456 [containerView_ setHidden:YES]; 478 [containerView_ setHidden:YES];
457 } else { 479 } else {
458 [self repositionActionButtons]; 480 [self repositionActionButtonsAndAnimate:NO];
459 } 481 }
460 [containerView_ setMaxWidth: 482 [containerView_ setMaxWidth:
461 [self containerWidthWithButtonCount:[self buttonCount]]]; 483 [self containerWidthWithButtonCount:[self buttonCount]]];
462 [containerView_ setNeedsDisplay:YES]; 484 [containerView_ setNeedsDisplay:YES];
463 } 485 }
464 486
465 - (void)repositionActionButtons { 487 - (void)repositionActionButtonsAndAnimate:(BOOL)animate {
466 NSUInteger i = 0; 488 NSUInteger i = 0;
467 for (ExtensionList::iterator iter = toolbarModel_->begin(); 489 for (ExtensionList::iterator iter = toolbarModel_->begin();
468 iter != toolbarModel_->end(); ++iter) { 490 iter != toolbarModel_->end(); ++iter) {
469 if (![self shouldDisplayBrowserAction:*iter]) 491 if (![self shouldDisplayBrowserAction:*iter])
470 continue; 492 continue;
471
472 CGFloat xOffset = kGrippyXOffset +
473 (i * (kBrowserActionWidth + kBrowserActionButtonPadding));
474 BrowserActionButton* button = [self buttonForExtension:(*iter)]; 493 BrowserActionButton* button = [self buttonForExtension:(*iter)];
475 if (!button) 494 if (!button)
476 continue; 495 continue;
477 NSRect buttonFrame = [button frame]; 496 if (![button isBeingDragged])
478 buttonFrame.origin.x = xOffset; 497 [self moveButton:button toIndex:i animate:animate];
479 [button setFrame:buttonFrame];
480 ++i; 498 ++i;
481 } 499 }
482 } 500 }
483 501
484 - (void)updateButtonOpacity { 502 - (void)updateButtonOpacity {
485 for (BrowserActionButton* button in [buttons_ allValues]) { 503 for (BrowserActionButton* button in [buttons_ allValues]) {
486 NSRect buttonFrame = [button frame]; 504 NSRect buttonFrame = [button frame];
487 buttonFrame.origin.x += kButtonOpacityLeadPadding; 505 buttonFrame.origin.x += kButtonOpacityLeadPadding;
488 if (NSContainsRect([containerView_ bounds], buttonFrame)) { 506 if (NSContainsRect([containerView_ bounds], buttonFrame)) {
489 if ([button alphaValue] != 1.0) 507 if ([button alphaValue] != 1.0)
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 if (![hiddenButtons_ containsObject:button]) 598 if (![hiddenButtons_ containsObject:button])
581 return; 599 return;
582 600
583 // +1 item because of the title placeholder. See |updateOverflowMenu|. 601 // +1 item because of the title placeholder. See |updateOverflowMenu|.
584 NSUInteger menuIndex = [hiddenButtons_ indexOfObject:button] + 1; 602 NSUInteger menuIndex = [hiddenButtons_ indexOfObject:button] + 1;
585 NSMenuItem* item = [[chevronMenuButton_ attachedMenu] itemAtIndex:menuIndex]; 603 NSMenuItem* item = [[chevronMenuButton_ attachedMenu] itemAtIndex:menuIndex];
586 DCHECK(button == [item representedObject]); 604 DCHECK(button == [item representedObject]);
587 [item setImage:[button compositedImage]]; 605 [item setImage:[button compositedImage]];
588 } 606 }
589 607
608 - (void)actionButtonDragging:(NSNotification*)notification {
609 if (![self chevronIsHidden])
610 [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES];
611
612 // Determine what index the dragged button should lie in, alter the model and
613 // reposition the buttons.
614 CGFloat dragThreshold = std::floor(kBrowserActionWidth / 2);
615 BrowserActionButton* draggedButton = [notification object];
616 NSRect draggedButtonFrame = [draggedButton frame];
617
618 NSUInteger index = 0;
619 for (ExtensionList::iterator iter = toolbarModel_->begin();
620 iter != toolbarModel_->end(); ++iter) {
621 BrowserActionButton* button = [self buttonForExtension:(*iter)];
622 CGFloat intersectionWidth =
623 NSWidth(NSIntersectionRect(draggedButtonFrame, [button frame]));
624
625 if (intersectionWidth > dragThreshold && button != draggedButton &&
626 ![button isAnimating]) {
627 toolbarModel_->MoveBrowserAction([draggedButton extension], index);
628 [self repositionActionButtonsAndAnimate:YES];
629 return;
630 }
631 ++index;
632 }
633 }
634
635 - (void)actionButtonDragFinished:(NSNotification*)notification {
636 [self showChevronIfNecessaryInFrame:[containerView_ frame] animate:YES];
637 DCHECK(![[notification object] isBeingDragged]);
638 [self repositionActionButtonsAndAnimate:YES];
639 }
640
641 - (void)moveButton:(BrowserActionButton*)button
642 toIndex:(NSUInteger)index
643 animate:(BOOL)animate {
644 CGFloat xOffset = kGrippyXOffset +
645 (index * (kBrowserActionWidth + kBrowserActionButtonPadding));
646 NSRect buttonFrame = [button frame];
647 buttonFrame.origin.x = xOffset;
648 [button setFrame:buttonFrame animate:animate];
649 }
650
590 - (void)browserActionClicked:(BrowserActionButton*)button { 651 - (void)browserActionClicked:(BrowserActionButton*)button {
591 int tabId = [self currentTabId]; 652 int tabId = [self currentTabId];
592 if (tabId < 0) { 653 if (tabId < 0) {
593 NOTREACHED() << "No current tab."; 654 NOTREACHED() << "No current tab.";
594 return; 655 return;
595 } 656 }
596 657
597 ExtensionAction* action = [button extension]->browser_action(); 658 ExtensionAction* action = [button extension]->browser_action();
598 if (action->HasPopup(tabId)) { 659 if (action->HasPopup(tabId)) {
599 NSPoint arrowPoint = [self popupPointForBrowserAction:[button extension]]; 660 NSPoint arrowPoint = [self popupPointForBrowserAction:[button extension]];
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey, 723 NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey,
663 nil]; 724 nil];
664 } else { 725 } else {
665 [chevronMenuButton_ setHidden:NO]; 726 [chevronMenuButton_ setHidden:NO];
666 animationDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 727 animationDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
667 chevronMenuButton_.get(), NSViewAnimationTargetKey, 728 chevronMenuButton_.get(), NSViewAnimationTargetKey,
668 NSViewAnimationFadeInEffect, NSViewAnimationEffectKey, 729 NSViewAnimationFadeInEffect, NSViewAnimationEffectKey,
669 nil]; 730 nil];
670 } 731 }
671 [chevronAnimation_ setViewAnimations: 732 [chevronAnimation_ setViewAnimations:
672 [NSArray arrayWithObjects:animationDictionary, nil]]; 733 [NSArray arrayWithObject:animationDictionary]];
673 [chevronAnimation_ startAnimation]; 734 [chevronAnimation_ startAnimation];
674 } 735 }
675 736
676 - (void)chevronItemSelected:(id)menuItem { 737 - (void)chevronItemSelected:(id)menuItem {
677 [self browserActionClicked:[menuItem representedObject]]; 738 [self browserActionClicked:[menuItem representedObject]];
678 } 739 }
679 740
680 - (void)updateOverflowMenu { 741 - (void)updateOverflowMenu {
681 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]); 742 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]);
682 // See menu_button.h for documentation on why this is needed. 743 // See menu_button.h for documentation on why this is needed.
(...skipping 29 matching lines...) Expand all
712 iter != toolbarModel_->end(); ++iter) { 773 iter != toolbarModel_->end(); ++iter) {
713 if (i == index) 774 if (i == index)
714 return [buttons_ objectForKey:base::SysUTF8ToNSString((*iter)->id())]; 775 return [buttons_ objectForKey:base::SysUTF8ToNSString((*iter)->id())];
715 776
716 ++i; 777 ++i;
717 } 778 }
718 return nil; 779 return nil;
719 } 780 }
720 781
721 @end 782 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/extensions/browser_action_button.mm ('k') | chrome/browser/cocoa/toolbar_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698