OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <cmath> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 - (void)containerDragStart:(NSNotification*)notification; | 114 - (void)containerDragStart:(NSNotification*)notification; |
115 | 115 |
116 // Sends a notification for the toolbar to reposition surrounding UI elements. | 116 // Sends a notification for the toolbar to reposition surrounding UI elements. |
117 - (void)containerDragging:(NSNotification*)notification; | 117 - (void)containerDragging:(NSNotification*)notification; |
118 | 118 |
119 // Determines which buttons need to be hidden based on the new size, hides them | 119 // Determines which buttons need to be hidden based on the new size, hides them |
120 // and updates the chevron overflow menu. Also fires a notification to let the | 120 // and updates the chevron overflow menu. Also fires a notification to let the |
121 // toolbar know that the drag has finished. | 121 // toolbar know that the drag has finished. |
122 - (void)containerDragFinished:(NSNotification*)notification; | 122 - (void)containerDragFinished:(NSNotification*)notification; |
123 | 123 |
124 // Updates the image associated with the button should it be within the chevron | |
125 // menu. | |
126 - (void)actionButtonUpdated:(NSNotification*)notification; | |
127 | |
128 // Adjusts the position of the surrounding action buttons depending on where the | 124 // Adjusts the position of the surrounding action buttons depending on where the |
129 // button is within the container. | 125 // button is within the container. |
130 - (void)actionButtonDragging:(NSNotification*)notification; | 126 - (void)actionButtonDragging:(NSNotification*)notification; |
131 | 127 |
132 // Updates the position of the Browser Actions within the container. This fires | 128 // Updates the position of the Browser Actions within the container. This fires |
133 // when _any_ Browser Action button is done dragging to keep all open windows in | 129 // when _any_ Browser Action button is done dragging to keep all open windows in |
134 // sync visually. | 130 // sync visually. |
135 - (void)actionButtonDragFinished:(NSNotification*)notification; | 131 - (void)actionButtonDragFinished:(NSNotification*)notification; |
136 | 132 |
137 // Moves the given button both visually and within the toolbar model to the | 133 // Moves the given button both visually and within the toolbar model to the |
(...skipping 22 matching lines...) Expand all Loading... | |
160 - (void)updateChevronPositionInFrame:(NSRect)frame; | 156 - (void)updateChevronPositionInFrame:(NSRect)frame; |
161 | 157 |
162 // Shows or hides the chevron, animating as specified by |animate|. | 158 // Shows or hides the chevron, animating as specified by |animate|. |
163 - (void)setChevronHidden:(BOOL)hidden | 159 - (void)setChevronHidden:(BOOL)hidden |
164 inFrame:(NSRect)frame | 160 inFrame:(NSRect)frame |
165 animate:(BOOL)animate; | 161 animate:(BOOL)animate; |
166 | 162 |
167 // Handles when a menu item within the chevron overflow menu is selected. | 163 // Handles when a menu item within the chevron overflow menu is selected. |
168 - (void)chevronItemSelected:(id)menuItem; | 164 - (void)chevronItemSelected:(id)menuItem; |
169 | 165 |
166 // NSMenuDelegate override: | |
170 // Clears and then populates the overflow menu based on the contents of | 167 // Clears and then populates the overflow menu based on the contents of |
171 // |hiddenButtons_|. | 168 // |hiddenButtons_|. |
172 - (void)updateOverflowMenu; | 169 - (void)menuNeedsUpdate:(NSMenu*)menu; |
Robert Sesek
2012/07/23 17:39:40
Can remove
Yoyo Zhou
2012/07/23 18:47:24
Removed.
| |
173 | 170 |
174 // Updates the container's grippy cursor based on the number of hidden buttons. | 171 // Updates the container's grippy cursor based on the number of hidden buttons. |
175 - (void)updateGrippyCursors; | 172 - (void)updateGrippyCursors; |
176 | 173 |
177 // Returns the ID of the currently selected tab or -1 if none exists. | 174 // Returns the ID of the currently selected tab or -1 if none exists. |
178 - (int)currentTabId; | 175 - (int)currentTabId; |
179 @end | 176 @end |
180 | 177 |
181 // A helper class to proxy extension notifications to the view controller's | 178 // A helper class to proxy extension notifications to the view controller's |
182 // appropriate methods. | 179 // appropriate methods. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 | 428 |
432 NSUInteger i = 0; | 429 NSUInteger i = 0; |
433 for (ExtensionList::iterator iter = toolbarModel_->begin(); | 430 for (ExtensionList::iterator iter = toolbarModel_->begin(); |
434 iter != toolbarModel_->end(); ++iter) { | 431 iter != toolbarModel_->end(); ++iter) { |
435 if (![self shouldDisplayBrowserAction:*iter]) | 432 if (![self shouldDisplayBrowserAction:*iter]) |
436 continue; | 433 continue; |
437 | 434 |
438 [self createActionButtonForExtension:*iter withIndex:i++]; | 435 [self createActionButtonForExtension:*iter withIndex:i++]; |
439 } | 436 } |
440 | 437 |
441 [[NSNotificationCenter defaultCenter] | |
442 addObserver:self | |
443 selector:@selector(actionButtonUpdated:) | |
444 name:kBrowserActionButtonUpdatedNotification | |
445 object:nil]; | |
446 | |
447 CGFloat width = [self savedWidth]; | 438 CGFloat width = [self savedWidth]; |
448 [containerView_ resizeToWidth:width animate:NO]; | 439 [containerView_ resizeToWidth:width animate:NO]; |
449 } | 440 } |
450 | 441 |
451 - (void)createActionButtonForExtension:(const Extension*)extension | 442 - (void)createActionButtonForExtension:(const Extension*)extension |
452 withIndex:(NSUInteger)index { | 443 withIndex:(NSUInteger)index { |
453 if (!extension->browser_action()) | 444 if (!extension->browser_action()) |
454 return; | 445 return; |
455 | 446 |
456 if (![self shouldDisplayBrowserAction:extension]) | 447 if (![self shouldDisplayBrowserAction:extension]) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
504 BrowserActionButton* button = [buttons_ objectForKey:buttonKey]; | 495 BrowserActionButton* button = [buttons_ objectForKey:buttonKey]; |
505 // This could be the case in incognito, where only a subset of extensions are | 496 // This could be the case in incognito, where only a subset of extensions are |
506 // shown. | 497 // shown. |
507 if (!button) | 498 if (!button) |
508 return; | 499 return; |
509 | 500 |
510 [button removeFromSuperview]; | 501 [button removeFromSuperview]; |
511 // It may or may not be hidden, but it won't matter to NSMutableArray either | 502 // It may or may not be hidden, but it won't matter to NSMutableArray either |
512 // way. | 503 // way. |
513 [hiddenButtons_ removeObject:button]; | 504 [hiddenButtons_ removeObject:button]; |
514 [self updateOverflowMenu]; | |
515 | 505 |
516 [buttons_ removeObjectForKey:buttonKey]; | 506 [buttons_ removeObjectForKey:buttonKey]; |
517 if ([self buttonCount] == 0) { | 507 if ([self buttonCount] == 0) { |
518 // No more buttons? Hide the container. | 508 // No more buttons? Hide the container. |
519 [containerView_ setHidden:YES]; | 509 [containerView_ setHidden:YES]; |
520 } else { | 510 } else { |
521 [self positionActionButtonsAndAnimate:NO]; | 511 [self positionActionButtonsAndAnimate:NO]; |
522 } | 512 } |
523 [containerView_ setMaxWidth: | 513 [containerView_ setMaxWidth: |
524 [self containerWidthWithButtonCount:[self buttonCount]]]; | 514 [self containerWidthWithButtonCount:[self buttonCount]]]; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
629 NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); | 619 NSWidth(NSIntersectionRect([containerView_ bounds], buttonFrame)); |
630 // Pad the threshold by 5 pixels in order to have the buttons hide more | 620 // Pad the threshold by 5 pixels in order to have the buttons hide more |
631 // easily. | 621 // easily. |
632 if (([containerView_ grippyPinned] && intersectionWidth > 0) || | 622 if (([containerView_ grippyPinned] && intersectionWidth > 0) || |
633 (intersectionWidth <= (NSWidth(buttonFrame) / 2) + 5.0)) { | 623 (intersectionWidth <= (NSWidth(buttonFrame) / 2) + 5.0)) { |
634 [button setAlphaValue:0.0]; | 624 [button setAlphaValue:0.0]; |
635 [button removeFromSuperview]; | 625 [button removeFromSuperview]; |
636 [hiddenButtons_ addObject:button]; | 626 [hiddenButtons_ addObject:button]; |
637 } | 627 } |
638 } | 628 } |
639 [self updateOverflowMenu]; | |
640 [self updateGrippyCursors]; | 629 [self updateGrippyCursors]; |
641 | 630 |
642 if (!profile_->IsOffTheRecord()) | 631 if (!profile_->IsOffTheRecord()) |
643 toolbarModel_->SetVisibleIconCount([self visibleButtonCount]); | 632 toolbarModel_->SetVisibleIconCount([self visibleButtonCount]); |
644 | 633 |
645 [[NSNotificationCenter defaultCenter] | 634 [[NSNotificationCenter defaultCenter] |
646 postNotificationName:kBrowserActionGrippyDragFinishedNotification | 635 postNotificationName:kBrowserActionGrippyDragFinishedNotification |
647 object:self]; | 636 object:self]; |
648 } | 637 } |
649 | 638 |
650 - (void)actionButtonUpdated:(NSNotification*)notification { | |
651 BrowserActionButton* button = [notification object]; | |
652 if (![hiddenButtons_ containsObject:button]) | |
653 return; | |
654 | |
655 // +1 item because of the title placeholder. See |updateOverflowMenu|. | |
656 NSUInteger menuIndex = [hiddenButtons_ indexOfObject:button] + 1; | |
657 NSMenuItem* item = [[chevronMenuButton_ attachedMenu] itemAtIndex:menuIndex]; | |
658 DCHECK(button == [item representedObject]); | |
659 [item setImage:[button compositedImage]]; | |
660 } | |
661 | |
662 - (void)actionButtonDragging:(NSNotification*)notification { | 639 - (void)actionButtonDragging:(NSNotification*)notification { |
663 if (![self chevronIsHidden]) | 640 if (![self chevronIsHidden]) |
664 [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES]; | 641 [self setChevronHidden:YES inFrame:[containerView_ frame] animate:YES]; |
665 | 642 |
666 // Determine what index the dragged button should lie in, alter the model and | 643 // Determine what index the dragged button should lie in, alter the model and |
667 // reposition the buttons. | 644 // reposition the buttons. |
668 CGFloat dragThreshold = std::floor(kBrowserActionWidth / 2); | 645 CGFloat dragThreshold = std::floor(kBrowserActionWidth / 2); |
669 BrowserActionButton* draggedButton = [notification object]; | 646 BrowserActionButton* draggedButton = [notification object]; |
670 NSRect draggedButtonFrame = [draggedButton frame]; | 647 NSRect draggedButtonFrame = [draggedButton frame]; |
671 | 648 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
704 // Make sure the button is within the visible container. | 681 // Make sure the button is within the visible container. |
705 if ([button superview] != containerView_) { | 682 if ([button superview] != containerView_) { |
706 [containerView_ addSubview:button]; | 683 [containerView_ addSubview:button]; |
707 [button setAlphaValue:1.0]; | 684 [button setAlphaValue:1.0]; |
708 [hiddenButtons_ removeObjectIdenticalTo:button]; | 685 [hiddenButtons_ removeObjectIdenticalTo:button]; |
709 } | 686 } |
710 } else if (![hiddenButtons_ containsObject:button]) { | 687 } else if (![hiddenButtons_ containsObject:button]) { |
711 [hiddenButtons_ addObject:button]; | 688 [hiddenButtons_ addObject:button]; |
712 [button removeFromSuperview]; | 689 [button removeFromSuperview]; |
713 [button setAlphaValue:0.0]; | 690 [button setAlphaValue:0.0]; |
714 [self updateOverflowMenu]; | |
715 } | 691 } |
716 } | 692 } |
717 | 693 |
718 - (void)browserActionClicked:(BrowserActionButton*)button { | 694 - (void)browserActionClicked:(BrowserActionButton*)button { |
719 const Extension* extension = [button extension]; | 695 const Extension* extension = [button extension]; |
720 GURL popupUrl; | 696 GURL popupUrl; |
721 switch (toolbarModel_->ExecuteBrowserAction(extension, browser_, &popupUrl)) { | 697 switch (toolbarModel_->ExecuteBrowserAction(extension, browser_, &popupUrl)) { |
722 case ExtensionToolbarModel::ACTION_NONE: | 698 case ExtensionToolbarModel::ACTION_NONE: |
723 break; | 699 break; |
724 case ExtensionToolbarModel::ACTION_SHOW_POPUP: { | 700 case ExtensionToolbarModel::ACTION_SHOW_POPUP: { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 [chevronMenuButton_ setBordered:NO]; | 743 [chevronMenuButton_ setBordered:NO]; |
768 [chevronMenuButton_ setShowsBorderOnlyWhileMouseInside:YES]; | 744 [chevronMenuButton_ setShowsBorderOnlyWhileMouseInside:YES]; |
769 | 745 |
770 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW | 746 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW |
771 forButtonState:image_button_cell::kDefaultState]; | 747 forButtonState:image_button_cell::kDefaultState]; |
772 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_H | 748 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_H |
773 forButtonState:image_button_cell::kHoverState]; | 749 forButtonState:image_button_cell::kHoverState]; |
774 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_P | 750 [[chevronMenuButton_ cell] setImageID:IDR_BROWSER_ACTIONS_OVERFLOW_P |
775 forButtonState:image_button_cell::kPressedState]; | 751 forButtonState:image_button_cell::kPressedState]; |
776 | 752 |
753 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]); | |
754 [overflowMenu_ setAutoenablesItems:NO]; | |
755 [overflowMenu_ setDelegate:self]; | |
756 [chevronMenuButton_ setAttachedMenu:overflowMenu_]; | |
757 | |
777 [containerView_ addSubview:chevronMenuButton_]; | 758 [containerView_ addSubview:chevronMenuButton_]; |
778 } | 759 } |
779 | 760 |
780 if (!hidden) | |
781 [self updateOverflowMenu]; | |
782 | |
783 [self updateChevronPositionInFrame:frame]; | 761 [self updateChevronPositionInFrame:frame]; |
784 | 762 |
785 // Stop any running animation. | 763 // Stop any running animation. |
786 [chevronAnimation_ stopAnimation]; | 764 [chevronAnimation_ stopAnimation]; |
787 | 765 |
788 if (!animate) { | 766 if (!animate) { |
789 [chevronMenuButton_ setHidden:hidden]; | 767 [chevronMenuButton_ setHidden:hidden]; |
790 return; | 768 return; |
791 } | 769 } |
792 | 770 |
(...skipping 12 matching lines...) Expand all Loading... | |
805 } | 783 } |
806 [chevronAnimation_ setViewAnimations: | 784 [chevronAnimation_ setViewAnimations: |
807 [NSArray arrayWithObject:animationDictionary]]; | 785 [NSArray arrayWithObject:animationDictionary]]; |
808 [chevronAnimation_ startAnimation]; | 786 [chevronAnimation_ startAnimation]; |
809 } | 787 } |
810 | 788 |
811 - (void)chevronItemSelected:(id)menuItem { | 789 - (void)chevronItemSelected:(id)menuItem { |
812 [self browserActionClicked:[menuItem representedObject]]; | 790 [self browserActionClicked:[menuItem representedObject]]; |
813 } | 791 } |
814 | 792 |
815 // TODO(yoz): This only gets called when the set of actions in the overflow | 793 - (void)menuNeedsUpdate:(NSMenu*)menu { |
816 // menu changes (not for things that would update page actions). | 794 [menu removeAllItems]; |
Robert Sesek
2012/07/23 17:39:40
nit: blank line after.
Yoyo Zhou
2012/07/23 18:47:24
Done.
| |
817 // It should instead be called each time the menu is opened. | 795 // See menu_button.h for documentation on why this is needed. |
Robert Sesek
2012/07/23 17:39:40
nit: indention
Yoyo Zhou
2012/07/23 18:47:24
Done.
| |
818 - (void)updateOverflowMenu { | 796 [menu addItemWithTitle:@"" action:nil keyEquivalent:@""]; |
819 overflowMenu_.reset([[NSMenu alloc] initWithTitle:@""]); | |
820 // See menu_button.h for documentation on why this is needed. | |
821 [overflowMenu_ addItemWithTitle:@"" action:nil keyEquivalent:@""]; | |
822 [overflowMenu_ setAutoenablesItems:NO]; | |
823 | 797 |
824 for (BrowserActionButton* button in hiddenButtons_.get()) { | 798 for (BrowserActionButton* button in hiddenButtons_.get()) { |
825 NSString* name = base::SysUTF8ToNSString([button extension]->name()); | 799 NSString* name = base::SysUTF8ToNSString([button extension]->name()); |
826 NSMenuItem* item = | 800 NSMenuItem* item = |
827 [overflowMenu_ addItemWithTitle:name | 801 [menu addItemWithTitle:name |
828 action:@selector(chevronItemSelected:) | 802 action:@selector(chevronItemSelected:) |
829 keyEquivalent:@""]; | 803 keyEquivalent:@""]; |
830 [item setRepresentedObject:button]; | 804 [item setRepresentedObject:button]; |
831 [item setImage:[button compositedImage]]; | 805 [item setImage:[button compositedImage]]; |
832 [item setTarget:self]; | 806 [item setTarget:self]; |
833 [item setEnabled:[button isEnabled]]; | 807 [item setEnabled:[button isEnabled]]; |
834 } | 808 } |
835 [chevronMenuButton_ setAttachedMenu:overflowMenu_]; | |
836 } | 809 } |
837 | 810 |
838 - (void)updateGrippyCursors { | 811 - (void)updateGrippyCursors { |
839 [containerView_ setCanDragLeft:[hiddenButtons_ count] > 0]; | 812 [containerView_ setCanDragLeft:[hiddenButtons_ count] > 0]; |
840 [containerView_ setCanDragRight:[self visibleButtonCount] > 0]; | 813 [containerView_ setCanDragRight:[self visibleButtonCount] > 0]; |
841 [[containerView_ window] invalidateCursorRectsForView:containerView_]; | 814 [[containerView_ window] invalidateCursorRectsForView:containerView_]; |
842 } | 815 } |
843 | 816 |
844 - (int)currentTabId { | 817 - (int)currentTabId { |
845 TabContents* selected_tab = chrome::GetActiveTabContents(browser_); | 818 TabContents* selected_tab = chrome::GetActiveTabContents(browser_); |
(...skipping 10 matching lines...) Expand all Loading... | |
856 if (profile_->IsOffTheRecord()) | 829 if (profile_->IsOffTheRecord()) |
857 index = toolbarModel_->IncognitoIndexToOriginal(index); | 830 index = toolbarModel_->IncognitoIndexToOriginal(index); |
858 if (index < toolbarModel_->size()) { | 831 if (index < toolbarModel_->size()) { |
859 const Extension* extension = toolbarModel_->GetExtensionByIndex(index); | 832 const Extension* extension = toolbarModel_->GetExtensionByIndex(index); |
860 return [buttons_ objectForKey:base::SysUTF8ToNSString(extension->id())]; | 833 return [buttons_ objectForKey:base::SysUTF8ToNSString(extension->id())]; |
861 } | 834 } |
862 return nil; | 835 return nil; |
863 } | 836 } |
864 | 837 |
865 @end | 838 @end |
OLD | NEW |