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

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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 void BrowserActionsContainer::ExecuteExtensionCommand( 262 void BrowserActionsContainer::ExecuteExtensionCommand(
263 const extensions::Extension* extension, 263 const extensions::Extension* extension,
264 const extensions::Command& command) { 264 const extensions::Command& command) {
265 // Global commands are handled by the ExtensionCommandsGlobalRegistry 265 // Global commands are handled by the ExtensionCommandsGlobalRegistry
266 // instance. 266 // instance.
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 void BrowserActionsContainer::NotifyActionMovedToOverflow() {
273 // When an action is moved to overflow, we shrink the size of the container
274 // by 1.
275 if (!profile_->IsOffTheRecord())
276 model_->SetVisibleIconCount(model_->GetVisibleIconCount() - 1);
277 Animate(gfx::Tween::EASE_OUT,
278 VisibleBrowserActionsAfterAnimation() - 1);
279 }
280
272 bool BrowserActionsContainer::ShownInsideMenu() const { 281 bool BrowserActionsContainer::ShownInsideMenu() const {
273 return in_overflow_mode(); 282 return in_overflow_mode();
274 } 283 }
275 284
276 void BrowserActionsContainer::OnBrowserActionViewDragDone() { 285 void BrowserActionsContainer::OnBrowserActionViewDragDone() {
277 // We notify here as well as in OnPerformDrop because the dragged view is 286 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, 287 FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
281 observers_, 288 observers_,
282 OnBrowserActionDragDone()); 289 OnBrowserActionDragDone());
283 } 290 }
284 291
285 views::View* BrowserActionsContainer::GetOverflowReferenceView() { 292 views::View* BrowserActionsContainer::GetOverflowReferenceView() {
286 // We should only need an overflow reference when using the traditional 293 // We should only need an overflow reference when using the traditional
287 // chevron overflow. 294 // chevron overflow.
288 DCHECK(chevron_); 295 DCHECK(chevron_);
289 return chevron_; 296 return chevron_;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 return BrowserActionDragData::AreDropTypesRequired(); 424 return BrowserActionDragData::AreDropTypesRequired();
418 } 425 }
419 426
420 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) { 427 bool BrowserActionsContainer::CanDrop(const OSExchangeData& data) {
421 return BrowserActionDragData::CanDrop(data, profile_); 428 return BrowserActionDragData::CanDrop(data, profile_);
422 } 429 }
423 430
424 int BrowserActionsContainer::OnDragUpdated( 431 int BrowserActionsContainer::OnDragUpdated(
425 const ui::DropTargetEvent& event) { 432 const ui::DropTargetEvent& event) {
426 // First check if we are above the chevron (overflow) menu. 433 // First check if we are above the chevron (overflow) menu.
427 if (GetEventHandlerForPoint(event.location()) == chevron_) { 434 if (chevron_ && GetEventHandlerForPoint(event.location()) == chevron_) {
428 if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_) 435 if (!show_menu_task_factory_.HasWeakPtrs() && !overflow_menu_)
429 StartShowFolderDropMenuTimer(); 436 StartShowFolderDropMenuTimer();
430 return ui::DragDropTypes::DRAG_MOVE; 437 return ui::DragDropTypes::DRAG_MOVE;
431 } 438 }
432 StopShowFolderDropMenuTimer(); 439 StopShowFolderDropMenuTimer();
433 440
434 // Figure out where to display the indicator. This is a complex calculation: 441 // Figure out where to display the indicator. This is a complex calculation:
435 442
436 // First, we figure out how much space is to the left of the icon area, so we 443 // 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 444 // 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, 537 // 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 538 // 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. 539 // 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. :) 540 // * Well, it can also point to the end, but not when dragging to the left. :)
534 if (i > data.index()) 541 if (i > data.index())
535 --i; 542 --i;
536 543
537 if (profile_->IsOffTheRecord()) 544 if (profile_->IsOffTheRecord())
538 i = model_->IncognitoIndexToOriginal(i); 545 i = model_->IncognitoIndexToOriginal(i);
539 546
547 // If this was a drag between containers, we will have to adjust the number of
548 // visible icons.
549 bool drag_between_containers =
550 !browser_action_views_[data.index()]->visible();
540 model_->MoveExtensionIcon( 551 model_->MoveExtensionIcon(
541 browser_action_views_[data.index()]->extension(), i); 552 browser_action_views_[data.index()]->extension(), i);
542 553
554 if (drag_between_containers) {
555 // Let the main container update the model.
556 if (in_overflow_mode())
557 main_container_->NotifyActionMovedToOverflow();
558 else if (!profile_->IsOffTheRecord()) // This is the main container.
Finnur 2014/09/11 09:23:48 What happens if you drop an icon onto the main con
Devlin 2014/09/11 17:46:05 tl;dr: All fixed. :) As it turns out, this partic
559 model_->SetVisibleIconCount(model_->GetVisibleIconCount() + 1);
560
561 // The size changed, so we need to animate.
562 Animate(gfx::Tween::EASE_OUT, GetIconCount());
563 }
564
543 OnDragExited(); // Perform clean up after dragging. 565 OnDragExited(); // Perform clean up after dragging.
544 FOR_EACH_OBSERVER(BrowserActionsContainerObserver,
545 observers_,
546 OnBrowserActionDragDone());
547 return ui::DragDropTypes::DRAG_MOVE; 566 return ui::DragDropTypes::DRAG_MOVE;
548 } 567 }
549 568
550 void BrowserActionsContainer::GetAccessibleState( 569 void BrowserActionsContainer::GetAccessibleState(
551 ui::AXViewState* state) { 570 ui::AXViewState* state) {
552 state->role = ui::AX_ROLE_GROUP; 571 state->role = ui::AX_ROLE_GROUP;
553 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS); 572 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_EXTENSIONS);
554 } 573 }
555 574
556 void BrowserActionsContainer::OnMenuButtonClicked(views::View* source, 575 void BrowserActionsContainer::OnMenuButtonClicked(views::View* source,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 637
619 // Save off the desired number of visible icons. We do this now instead of at 638 // 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 639 // 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. 640 // 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 641 // 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 642 // 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. 643 // always at least as wide as in an incognito window.
625 int visible_icons = WidthToIconCount(container_width_); 644 int visible_icons = WidthToIconCount(container_width_);
626 if (!profile_->IsOffTheRecord()) 645 if (!profile_->IsOffTheRecord())
627 model_->SetVisibleIconCount(visible_icons); 646 model_->SetVisibleIconCount(visible_icons);
628
629 Animate(gfx::Tween::EASE_OUT, visible_icons); 647 Animate(gfx::Tween::EASE_OUT, visible_icons);
630 } 648 }
631 649
632 void BrowserActionsContainer::AnimationProgressed( 650 void BrowserActionsContainer::AnimationProgressed(
633 const gfx::Animation* animation) { 651 const gfx::Animation* animation) {
634 DCHECK_EQ(resize_animation_.get(), animation); 652 DCHECK_EQ(resize_animation_.get(), animation);
635 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() * 653 resize_amount_ = static_cast<int>(resize_animation_->GetCurrentValue() *
636 (container_width_ - animation_target_size_)); 654 (container_width_ - animation_target_size_));
637 OnBrowserActionVisibilityChanged(); 655 OnBrowserActionVisibilityChanged();
638 } 656 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 690
673 size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const { 691 size_t BrowserActionsContainer::GetFirstVisibleIconIndex() const {
674 return in_overflow_mode() ? model_->GetVisibleIconCount() : 0; 692 return in_overflow_mode() ? model_->GetVisibleIconCount() : 0;
675 } 693 }
676 694
677 ExtensionPopup* BrowserActionsContainer::TestGetPopup() { 695 ExtensionPopup* BrowserActionsContainer::TestGetPopup() {
678 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL; 696 return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL;
679 } 697 }
680 698
681 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) { 699 void BrowserActionsContainer::TestSetIconVisibilityCount(size_t icons) {
682 model_->SetVisibleIconCount(icons); 700 model_->SetVisibleIconCountForTest(icons);
683 chevron_->SetVisible(icons < browser_action_views_.size());
684 container_width_ = IconCountToWidth(icons, chevron_->visible());
685 Layout();
686 SchedulePaint();
687 } 701 }
688 702
689 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) { 703 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) {
690 // If the views haven't been initialized yet, wait for the next call to 704 // If the views haven't been initialized yet, wait for the next call to
691 // paint (one will be triggered by entering highlight mode). 705 // paint (one will be triggered by entering highlight mode).
692 if (model_->is_highlighting() && !browser_action_views_.empty()) { 706 if (model_->is_highlighting() && !browser_action_views_.empty()) {
693 views::Painter::PaintPainterAt( 707 views::Painter::PaintPainterAt(
694 canvas, highlight_painter_.get(), GetLocalBounds()); 708 canvas, highlight_painter_.get(), GetLocalBounds());
695 } 709 }
696 710
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 959
946 const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); 960 const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT);
947 highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages)); 961 highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages));
948 } 962 }
949 963
950 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() { 964 void BrowserActionsContainer::OnBrowserActionVisibilityChanged() {
951 SetVisible(!browser_action_views_.empty()); 965 SetVisible(!browser_action_views_.empty());
952 if (owner_view_) { 966 if (owner_view_) {
953 owner_view_->Layout(); 967 owner_view_->Layout();
954 owner_view_->SchedulePaint(); 968 owner_view_->SchedulePaint();
969 } else {
970 // In overflow mode, we don't have an owner view, but we still have to
971 // update ourselves.
972 Layout();
973 SchedulePaint();
955 } 974 }
956 } 975 }
957 976
958 int BrowserActionsContainer::GetPreferredWidth() { 977 int BrowserActionsContainer::GetPreferredWidth() {
959 size_t visible_actions = GetIconCount(); 978 size_t visible_actions = GetIconCount();
960 return IconCountToWidth( 979 return IconCountToWidth(
961 visible_actions, 980 visible_actions,
962 chevron_ && visible_actions < browser_action_views_.size()); 981 chevron_ && visible_actions < browser_action_views_.size());
963 } 982 }
964 983
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0; 1029 (kChevronSpacing + chevron_->GetPreferredSize().width()) : 0;
1011 return ToolbarView::kStandardSpacing + icons_size + chevron_size + 1030 return ToolbarView::kStandardSpacing + icons_size + chevron_size +
1012 ToolbarView::kStandardSpacing; 1031 ToolbarView::kStandardSpacing;
1013 } 1032 }
1014 1033
1015 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const { 1034 size_t BrowserActionsContainer::WidthToIconCount(int pixels) const {
1016 // Check for widths large enough to show the entire icon set. 1035 // Check for widths large enough to show the entire icon set.
1017 if (pixels >= IconCountToWidth(-1, false)) 1036 if (pixels >= IconCountToWidth(-1, false))
1018 return browser_action_views_.size(); 1037 return browser_action_views_.size();
1019 1038
1020 // We need to reserve space for the resize area, chevron, and the spacing on 1039 // We reserve space for the padding on either side of the toolbar...
1021 // either side of the chevron. 1040 int available_space = pixels - (ToolbarView::kStandardSpacing * 2);
1022 int available_space = pixels - ToolbarView::kStandardSpacing - 1041 // ... and, if the chevron is enabled, the chevron.
1023 (chevron_ ? chevron_->GetPreferredSize().width() : 0) - 1042 if (chevron_)
1024 kChevronSpacing - ToolbarView::kStandardSpacing; 1043 available_space -= (chevron_->GetPreferredSize().width() + kChevronSpacing);
1044
1025 // Now we add an extra between-item padding value so the space can be divided 1045 // Now we add an extra between-item padding value so the space can be divided
1026 // evenly by (size of icon with padding). 1046 // evenly by (size of icon with padding).
1027 return static_cast<size_t>( 1047 return static_cast<size_t>(
1028 std::max(0, available_space + kItemSpacing) / IconWidth(true)); 1048 std::max(0, available_space + kItemSpacing) / IconWidth(true));
1029 } 1049 }
1030 1050
1031 int BrowserActionsContainer::MinimumNonemptyWidth() const { 1051 int BrowserActionsContainer::MinimumNonemptyWidth() const {
1032 if (!chevron_) 1052 if (!chevron_)
1033 return ToolbarView::kStandardSpacing; 1053 return ToolbarView::kStandardSpacing;
1034 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing + 1054 return (ToolbarView::kStandardSpacing * 2) + kChevronSpacing +
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 size_t absolute_model_size = 1094 size_t absolute_model_size =
1075 model_size == -1 ? extensions.size() : model_size; 1095 model_size == -1 ? extensions.size() : model_size;
1076 1096
1077 // The main container will try to show |model_size| icons, but reduce if there 1097 // The main container will try to show |model_size| icons, but reduce if there
1078 // aren't enough displayable icons to do so. 1098 // aren't enough displayable icons to do so.
1079 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size); 1099 size_t main_displayed = std::min(displayable_icon_count, absolute_model_size);
1080 // The overflow will display the extras, if any. 1100 // The overflow will display the extras, if any.
1081 return in_overflow_mode() ? 1101 return in_overflow_mode() ?
1082 displayable_icon_count - main_displayed : main_displayed; 1102 displayable_icon_count - main_displayed : main_displayed;
1083 } 1103 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698