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

Side by Side Diff: chrome/browser/ui/views/toolbar/browser_actions_container.cc

Issue 550313002: Pop extensions out of the action overflow menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/ui/views/toolbar/browser_actions_container.h" 5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "chrome/browser/extensions/extension_action_manager.h" 9 #include "chrome/browser/extensions/extension_action_manager.h"
10 #include "chrome/browser/extensions/extension_util.h" 10 #include "chrome/browser/extensions/extension_util.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 DCHECK(!command.global()); 267 DCHECK(!command.global());
268 extension_keybinding_registry_->ExecuteCommand(extension->id(), 268 extension_keybinding_registry_->ExecuteCommand(extension->id(),
269 command.accelerator()); 269 command.accelerator());
270 } 270 }
271 271
272 bool BrowserActionsContainer::ShownInsideMenu() const { 272 bool BrowserActionsContainer::ShownInsideMenu() const {
273 return in_overflow_mode(); 273 return in_overflow_mode();
274 } 274 }
275 275
276 void BrowserActionsContainer::OnBrowserActionViewDragDone() { 276 void BrowserActionsContainer::OnBrowserActionViewDragDone() {
277 // We notify here as well as in OnPerformDrop because the dragged view is 277 ToolbarVisibleCountChanged();
278 // removed in OnPerformDrop, so it will never get its OnDragDone() call.
279 // TODO(devlin): we should see about fixing that.
280 FOR_EACH_OBSERVER(BrowserActionsContainerObserver, 278 FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
281 observers_, 279 observers_,
282 OnBrowserActionDragDone()); 280 OnBrowserActionDragDone());
283 } 281 }
284 282
285 views::View* BrowserActionsContainer::GetOverflowReferenceView() { 283 views::View* BrowserActionsContainer::GetOverflowReferenceView() {
286 // We should only need an overflow reference when using the traditional 284 // We should only need an overflow reference when using the traditional
287 // chevron overflow. 285 // chevron overflow.
288 DCHECK(chevron_); 286 DCHECK(chevron_);
289 return chevron_; 287 return chevron_;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 return BrowserActionDragData::AreDropTypesRequired(); 415 return BrowserActionDragData::AreDropTypesRequired();
418 } 416 }
419 417
420 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { 418 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
421 return BrowserActionDragData::CanDrop(data, profile_); 419 return BrowserActionDragData::CanDrop(data, profile_);
422 } 420 }
423 421
424 int BrowserActionsContainer::OnDragUpdated( 422 int BrowserActionsContainer::OnDragUpdated(
425 const ui::DropTargetEvent& event) { 423 const ui::DropTargetEvent& event) {
426 // First check if we are above the chevron (overflow) menu. 424 // First check if we are above the chevron (overflow) menu.
427 if (GetEventHandlerForPoint(event.location()) == chevron_) { 425 if (chevron_ && GetEventHandlerForPoint(event.location()) == chevron_) {
428 if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_) 426 if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_)
429 StartShowFolderDropMenuTimer(); 427 StartShowFolderDropMenuTimer();
430 return ui::DragDropTypes::DRAG_MOVE; 428 return ui::DragDropTypes::DRAG_MOVE;
431 } 429 }
432 StopShowFolderDropMenuTimer(); 430 StopShowFolderDropMenuTimer();
433 431
434 // Figure out where to display the indicator. This is a complex calculation: 432 // Figure out where to display the indicator. This is a complex calculation:
435 433
436 // First, we figure out how much space is to the left of the icon area, so we 434 // First, we figure out how much space is to the left of the icon area, so we
437 // can calculate the true offset into the icon area. The easiest way to do 435 // can calculate the true offset into the icon area. The easiest way to do
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 // correct when dragging an icon to the left. When dragging to the right, 528 // correct when dragging an icon to the left. When dragging to the right,
531 // however, we want the icon being dragged to get the index of the item to 529 // however, we want the icon being dragged to get the index of the item to
532 // the left of the drop indicator, so we subtract one. 530 // the left of the drop indicator, so we subtract one.
533 // * Well, it can also point to the end, but not when dragging to the left. :) 531 // * Well, it can also point to the end, but not when dragging to the left. :)
534 if (i > data.index()) 532 if (i > data.index())
535 --i; 533 --i;
536 534
537 if (profile_->IsOffTheRecord()) 535 if (profile_->IsOffTheRecord())
538 i = model_->IncognitoIndexToOriginal(i); 536 i = model_->IncognitoIndexToOriginal(i);
539 537
538 // Check if the size of the toolbar needs to be adjusted; this happens when
539 // dragging from overflow to main or vice versa. We can check if this happened
540 // by seeing if the view is visible - if it's not, then the drag originated
541 // from the other container.
542 int size_modifier = 0;
543 if (!browser_action_views_[data.index()]->visible()) {
544 if (i > data.index()) {
Finnur 2014/09/10 09:48:01 I understand why dragging an icon to the left subt
Devlin 2014/09/10 15:58:30 Wow. Yeah, that's easier. Shoulda seen that... t
545 // Dragging to the right, so hiding one.
546 size_modifier = -1;
547 } else if (i < data.index()) {
548 // Dragging to the left, so showing one.
549 size_modifier = 1;
550 } else { // i == data.index()
551 // Edge case: dragging to the same index, but in the other menu.
552 // If this was *dropped* in the overflow container, then we're hiding one,
553 // otherwise we're showing one.
554 size_modifier = in_overflow_mode() ? -1 : 1;
555 }
556 }
557
540 model_->MoveExtensionIcon( 558 model_->MoveExtensionIcon(
541 browser_action_views_[data.index()]->extension(), i); 559 browser_action_views_[data.index()]->extension(), i);
542 560
561 // Adjust the size of the container, if needed.
562 if (size_modifier) {
563 // Let the main container update the model.
564 if (in_overflow_mode()) {
565 main_container_->NotifyActionMovedToOverflow();
566 } else if (!profile_->IsOffTheRecord()) {
567 model_->SetVisibleIconCount(
568 model_->GetVisibleIconCount() + size_modifier);
569 }
570
571 // The size changed, so we need to animate.
572 Animate(gfx::Tween::EASE_OUT, GetIconCount());
573 }
574
543 OnDragExited(); // Perform clean up after dragging. 575 OnDragExited(); // Perform clean up after dragging.
544 FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
545 observers_,
546 OnBrowserActionDragDone());
547 return ui::DragDropTypes::DRAG_MOVE; 576 return ui::DragDropTypes::DRAG_MOVE;
548 } 577 }
549 578
550 void BrowserActionsContainer::GetAccessibleState( 579 void BrowserActionsContainer::GetAccessibleState(
551 ui::AXViewState* state) { 580 ui::AXViewState* state) {
552 state->role = ui::AX_ROLE_GROUP; 581 state->role = ui::AX_ROLE_GROUP;
553 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS); 582 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS);
554 } 583 }
555 584
556 void BrowserActionsContainer::OnMenuButtonClicked(views::View* source, 585 void BrowserActionsContainer::OnMenuButtonClicked(views::View* source,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 647
619 // Save off the desired number of visible icons. We do this now instead of at 648 // Save off the desired number of visible icons. We do this now instead of at
620 // the end of the animation so that even if the browser is shut down while 649 // the end of the animation so that even if the browser is shut down while
621 // animating, the right value will be restored on next run. 650 // animating, the right value will be restored on next run.
622 // NOTE: Don't save the icon count in incognito because there may be fewer 651 // NOTE: Don't save the icon count in incognito because there may be fewer
623 // icons in that mode. The result is that the container in a normal window is 652 // icons in that mode. The result is that the container in a normal window is
624 // always at least as wide as in an incognito window. 653 // always at least as wide as in an incognito window.
625 int visible_icons = WidthToIconCount(container_width_); 654 int visible_icons = WidthToIconCount(container_width_);
626 if (!profile_->IsOffTheRecord()) 655 if (!profile_->IsOffTheRecord())
627 model_->SetVisibleIconCount(visible_icons); 656 model_->SetVisibleIconCount(visible_icons);
628
629 Animate(gfx::Tween::EASE_OUT, visible_icons); 657 Animate(gfx::Tween::EASE_OUT, visible_icons);
630 } 658 }
631 659
632 void BrowserActionsContainer::AnimationProgressed( 660 void BrowserActionsContainer::AnimationProgressed(
633 const gfx::Animation* animation) { 661 const gfx::Animation* animation) {
634 DCHECK_EQ(resize_animation_.get(), animation); 662 DCHECK_EQ(resize_animation_.get(), animation);
635 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() * 663 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() *
636 (container_width_ - animation_target_size_)); 664 (container_width_ - animation_target_size_));
637 OnBrowserActionVisibilityChanged(); 665 OnBrowserActionVisibilityChanged();
638 } 666 }
(...skipping 10 matching lines...) Expand all
649 observers_, 677 observers_,
650 OnBrowserActionsContainerAnimationEnded()); 678 OnBrowserActionsContainerAnimationEnded());
651 } 679 }
652 680
653 void BrowserActionsContainer::NotifyMenuDeleted( 681 void BrowserActionsContainer::NotifyMenuDeleted(
654 BrowserActionOverflowMenuController* controller) { 682 BrowserActionOverflowMenuController* controller) {
655 DCHECK_EQ(overflow_menu_, controller); 683 DCHECK_EQ(overflow_menu_, controller);
656 overflow_menu_ = NULL; 684 overflow_menu_ = NULL;
657 } 685 }
658 686
687 void BrowserActionsContainer::NotifyActionMovedToOverflow() {
688 // When an action is moved to overflow, we shrink the size of the container
689 // by 1.
690 if (!profile_->IsOffTheRecord())
691 model_->SetVisibleIconCount(model_->GetVisibleIconCount() - 1);
692 Animate(gfx::Tween::EASE_OUT,
693 VisibleBrowserActionsAfterAnimation() - 1);
694 }
695
659 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { 696 content::WebContents* BrowserActionsContainer::GetCurrentWebContents() {
660 return browser_->tab_strip_model()->GetActiveWebContents(); 697 return browser_->tab_strip_model()->GetActiveWebContents();
661 } 698 }
662 699
663 extensions::ActiveTabPermissionGranter* 700 extensions::ActiveTabPermissionGranter*
664 BrowserActionsContainer::GetActiveTabPermissionGranter() { 701 BrowserActionsContainer::GetActiveTabPermissionGranter() {
665 content::WebContents* web_contents = 702 content::WebContents* web_contents =
666 browser_->tab_strip_model()->GetActiveWebContents(); 703 browser_->tab_strip_model()->GetActiveWebContents();
667 if (!web_contents) 704 if (!web_contents)
668 return NULL; 705 return NULL;
669 return extensions::TabHelper::FromWebContents(web_contents)-> 706 return extensions::TabHelper::FromWebContents(web_contents)->
670 active_tab_permission_granter(); 707 active_tab_permission_granter();
671 } 708 }
672 709
673 size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const { 710 size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const {
674 return in_overflow_mode() ? model_->GetVisibleIconCount() : 0; 711 return in_overflow_mode() ? model_->GetVisibleIconCount() : 0;
675 } 712 }
676 713
677 ExtensionPopup* BrowserActionsContainer::TestGetPopup() { 714 ExtensionPopup* BrowserActionsContainer::TestGetPopup() {
678 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL; 715 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL;
679 } 716 }
680 717
681 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { 718 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
682 model_->SetVisibleIconCount(icons); 719 model_->SetVisibleIconCountForTest(icons);
683 chevron_->SetVisible(icons < browser_action_views_.size());
684 container_width_ = IconCountToWidth(icons, chevron_->visible());
685 Layout();
686 SchedulePaint();
687 } 720 }
688 721
689 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { 722 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) {
690 // If the views haven't been initialized yet, wait for the next call to 723 // If the views haven't been initialized yet, wait for the next call to
691 // paint (one will be triggered by entering highlight mode). 724 // paint (one will be triggered by entering highlight mode).
692 if (model_->is_highlighting() && !browser_action_views_.empty()) { 725 if (model_->is_highlighting() && !browser_action_views_.empty()) {
693 views::Painter::PaintPainterAt( 726 views::Painter::PaintPainterAt(
694 canvas, highlight_painter_.get(), GetLocalBounds()); 727 canvas, highlight_painter_.get(), GetLocalBounds());
695 } 728 }
696 729
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; 1043 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0;
1011 return ToolbarView::kStandardSpacing + icons_size + chevron_size + 1044 return ToolbarView::kStandardSpacing + icons_size + chevron_size +
1012 ToolbarView::kStandardSpacing; 1045 ToolbarView::kStandardSpacing;
1013 } 1046 }
1014 1047
1015 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { 1048 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const {
1016 // Check for widths large enough to show the entire icon set. 1049 // Check for widths large enough to show the entire icon set.
1017 if (pixels >= IconCountToWidth(-1, false)) 1050 if (pixels >= IconCountToWidth(-1, false))
1018 return browser_action_views_.size(); 1051 return browser_action_views_.size();
1019 1052
1020 // We need to reserve space for the resize area, chevron, and the spacing on 1053 // We reserve space for the padding on either side of the toolbar...
1021 // either side of the chevron. 1054 int available_space = pixels - (ToolbarView::kStandardSpacing * 2);
1022 int available_space = pixels - ToolbarView::kStandardSpacing - 1055 // ... and, if the chevron is enabled, the chevron.
1023 (chevron_ ? chevron_->GetPreferredSize().width() : 0) - 1056 if (chevron_)
1024 kChevronSpacing - ToolbarView::kStandardSpacing; 1057 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing);
1058
1025 // Now we add an extra between-item padding value so the space can be divided 1059 // Now we add an extra between-item padding value so the space can be divided
1026 // evenly by (size of icon with padding). 1060 // evenly by (size of icon with padding).
1027 return static_cast<size_t>( 1061 return static_cast<size_t>(
1028 std::max(0, available_space + kItemSpacing) / IconWidth(true)); 1062 std::max(0, available_space + kItemSpacing) / IconWidth(true));
1029 } 1063 }
1030 1064
1031 int BrowserActionsContainer::MinimumNonemptyWidth() const { 1065 int BrowserActionsContainer::MinimumNonemptyWidth() const {
1032 if (!chevron_) 1066 if (!chevron_)
1033 return ToolbarView::kStandardSpacing; 1067 return ToolbarView::kStandardSpacing;
1034 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + 1068 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing +
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 size_t absolute_model_size = 1108 size_t absolute_model_size =
1075 model_size == -1 ? extensions.size() : model_size; 1109 model_size == -1 ? extensions.size() : model_size;
1076 1110
1077 // The main container will try to show |model_size| icons, but reduce if there 1111 // The main container will try to show |model_size| icons, but reduce if there
1078 // aren't enough displayable icons to do so. 1112 // aren't enough displayable icons to do so.
1079 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); 1113 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size);
1080 // The overflow will display the extras, if any. 1114 // The overflow will display the extras, if any.
1081 return in_overflow_mode() ? 1115 return in_overflow_mode() ?
1082 displayable_icon_count - main_displayed : main_displayed; 1116 displayable_icon_count - main_displayed : main_displayed;
1083 } 1117 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698