Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / toolbar / extension_toolbar_menu_view.cc
blob1589d013adddf547d5040c97e2519e23887d20ec
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
13 #include "chrome/browser/ui/views/frame/browser_view.h"
14 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
15 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
16 #include "chrome/browser/ui/views/toolbar/wrench_menu.h"
17 #include "ui/views/controls/menu/menu_item_view.h"
18 #include "ui/views/controls/menu/submenu_view.h"
20 namespace {
21 // The delay before we close the wrench menu if this was opened for a drop so
22 // that the user can see a browser action if one was moved.
23 // This can be changed for tests.
24 int g_close_menu_delay = 300;
27 ExtensionToolbarMenuView::ExtensionToolbarMenuView(Browser* browser,
28 WrenchMenu* wrench_menu)
29 : browser_(browser),
30 wrench_menu_(wrench_menu),
31 container_(nullptr),
32 max_height_(0),
33 browser_actions_container_observer_(this),
34 weak_factory_(this) {
35 BrowserActionsContainer* main =
36 BrowserView::GetBrowserViewForBrowser(browser_)
37 ->toolbar()->browser_actions();
38 container_ = new BrowserActionsContainer(browser_, main);
39 container_->Init();
40 SetContents(container_);
41 // We Layout() the container here so that we know the number of actions
42 // that will be visible in ShouldShow().
43 container_->Layout();
45 // Listen for the drop to finish so we can close the wrench menu, if
46 // necessary.
47 browser_actions_container_observer_.Add(container_);
48 browser_actions_container_observer_.Add(main);
50 // In *very* extreme cases, it's possible that there are so many overflowed
51 // actions, we won't be able to show them all. Cap the height so that the
52 // overflow won't be excessively tall (at 8 icons per row, this allows for
53 // 104 total extensions).
54 const int kMaxOverflowRows = 13;
55 max_height_ = ToolbarActionsBar::IconHeight() * kMaxOverflowRows;
56 ClipHeightTo(0, max_height_);
59 ExtensionToolbarMenuView::~ExtensionToolbarMenuView() {
62 bool ExtensionToolbarMenuView::ShouldShow() {
63 return wrench_menu_->for_drop() ||
64 container_->VisibleBrowserActionsAfterAnimation();
67 gfx::Size ExtensionToolbarMenuView::GetPreferredSize() const {
68 gfx::Size s = views::ScrollView::GetPreferredSize();
69 // views::ScrollView::GetPreferredSize() includes the contents' size, but
70 // not the scrollbar width. Add it in if necessary.
71 if (container_->GetPreferredSize().height() > max_height_)
72 s.Enlarge(GetScrollBarWidth(), 0);
73 return s;
76 int ExtensionToolbarMenuView::GetHeightForWidth(int width) const {
77 // The width passed in here includes the full width of the menu, so we need
78 // to omit the necessary padding.
79 const views::MenuConfig& menu_config =
80 static_cast<const views::MenuItemView*>(parent())->GetMenuConfig();
81 int end_padding = menu_config.arrow_to_edge_padding -
82 container_->toolbar_actions_bar()->platform_settings().item_spacing;
83 width -= start_padding() + end_padding;
85 return views::ScrollView::GetHeightForWidth(width);
88 void ExtensionToolbarMenuView::Layout() {
89 SetPosition(gfx::Point(start_padding(), 0));
90 SizeToPreferredSize();
91 views::ScrollView::Layout();
94 void ExtensionToolbarMenuView::set_close_menu_delay_for_testing(int delay) {
95 g_close_menu_delay = delay;
98 void ExtensionToolbarMenuView::OnBrowserActionDragDone() {
99 // We need to close the wrench menu if it was just opened for the drag and
100 // drop, or if there are no more extensions in the overflow menu after a drag
101 // and drop
102 if (wrench_menu_->for_drop() ||
103 container_->toolbar_actions_bar()->GetIconCount() == 0) {
104 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
105 FROM_HERE, base::Bind(&ExtensionToolbarMenuView::CloseWrenchMenu,
106 weak_factory_.GetWeakPtr()),
107 base::TimeDelta::FromMilliseconds(g_close_menu_delay));
111 void ExtensionToolbarMenuView::CloseWrenchMenu() {
112 wrench_menu_->CloseMenu();
115 int ExtensionToolbarMenuView::start_padding() const {
116 // We pad enough on the left so that the first icon starts at the same point
117 // as the labels. We subtract kItemSpacing because there needs to be padding
118 // so we can see the drop indicator.
119 return views::MenuItemView::label_start() -
120 container_->toolbar_actions_bar()->platform_settings().item_spacing;