extension_toolbar_menu_view.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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.
4
5#include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/time/time.h"
10#include "chrome/browser/ui/views/frame/browser_view.h"
11#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
12#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
13#include "chrome/browser/ui/views/toolbar/wrench_menu.h"
14#include "ui/views/controls/menu/menu_item_view.h"
15#include "ui/views/controls/menu/submenu_view.h"
16
17namespace {
18
19// Returns the padding before the BrowserActionsContainer in the menu.
20int start_padding() {
21  // We pad enough on the left so that the first icon starts at the same point
22  // as the labels. We need to subtract 1 because we want the pixel *before*
23  // the label, and we subtract kItemSpacing because there needs to be padding
24  // so we can see the drop indicator.
25  return views::MenuItemView::label_start() - 1 -
26      BrowserActionsContainer::kItemSpacing;
27}
28
29}  // namespace
30
31ExtensionToolbarMenuView::ExtensionToolbarMenuView(Browser* browser,
32                                                   WrenchMenu* wrench_menu)
33    : browser_(browser),
34      wrench_menu_(wrench_menu),
35      container_(NULL),
36      browser_actions_container_observer_(this),
37      weak_factory_(this) {
38  BrowserActionsContainer* main =
39      BrowserView::GetBrowserViewForBrowser(browser_)
40          ->toolbar()->browser_actions();
41  container_ = new BrowserActionsContainer(
42      browser_,
43      NULL,  // No owner view, means no extra keybindings are registered.
44      main);
45  container_->Init();
46  AddChildView(container_);
47  // We Layout() the container here so that we know the number of actions
48  // that will be visible in ShouldShow().
49  container_->Layout();
50
51  // If we were opened for a drop command, we have to wait for the drop to
52  // finish so we can close the wrench menu.
53  if (wrench_menu_->for_drop()) {
54    browser_actions_container_observer_.Add(container_);
55    browser_actions_container_observer_.Add(main);
56  }
57}
58
59ExtensionToolbarMenuView::~ExtensionToolbarMenuView() {
60}
61
62bool ExtensionToolbarMenuView::ShouldShow() {
63  return wrench_menu_->for_drop() ||
64      container_->VisibleBrowserActionsAfterAnimation();
65}
66
67gfx::Size ExtensionToolbarMenuView::GetPreferredSize() const {
68  return container_->GetPreferredSize();
69}
70
71int ExtensionToolbarMenuView::GetHeightForWidth(int width) const {
72  const views::MenuConfig& menu_config =
73      static_cast<const views::MenuItemView*>(parent())->GetMenuConfig();
74  int end_padding = menu_config.arrow_to_edge_padding -
75                    BrowserActionsContainer::kItemSpacing;
76  width -= start_padding() + end_padding;
77
78  int height = container_->GetHeightForWidth(width);
79  return height;
80}
81
82void ExtensionToolbarMenuView::Layout() {
83  gfx::Size sz = GetPreferredSize();
84  SetBounds(start_padding() + 1, 0, sz.width(), sz.height());
85  container_->SetBounds(0, 0, sz.width(), sz.height());
86}
87
88void ExtensionToolbarMenuView::OnBrowserActionDragDone() {
89  // The delay before we close the wrench menu if this was opened for a drop so
90  // that the user can see a browser action if one was moved.
91  static const int kCloseMenuDelay = 300;
92
93  DCHECK(wrench_menu_->for_drop());
94  base::MessageLoop::current()->PostDelayedTask(
95      FROM_HERE,
96      base::Bind(&ExtensionToolbarMenuView::CloseWrenchMenu,
97                 weak_factory_.GetWeakPtr()),
98      base::TimeDelta::FromMilliseconds(kCloseMenuDelay));
99}
100
101void ExtensionToolbarMenuView::CloseWrenchMenu() {
102  wrench_menu_->CloseMenu();
103}
104