1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/views/frame/browser_view.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/wrench_menu.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/controls/menu/menu_item_view.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/views/controls/menu/submenu_view.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns the padding before the BrowserActionsContainer in the menu.
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint start_padding() {
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We pad enough on the left so that the first icon starts at the same point
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // as the labels. We need to subtract 1 because we want the pixel *before*
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the label, and we subtract kItemSpacing because there needs to be padding
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // so we can see the drop indicator.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return views::MenuItemView::label_start() - 1 -
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserActionsContainer::kItemSpacing;
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ExtensionToolbarMenuView::ExtensionToolbarMenuView(Browser* browser,
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                   WrenchMenu* wrench_menu)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : browser_(browser),
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      wrench_menu_(wrench_menu),
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      container_(NULL),
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      browser_actions_container_observer_(this),
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserActionsContainer* main =
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserView::GetBrowserViewForBrowser(browser_)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ->toolbar()->browser_actions();
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  container_ = new BrowserActionsContainer(
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      browser_,
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      NULL,  // No owner view, means no extra keybindings are registered.
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      main);
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  container_->Init();
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddChildView(container_);
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We Layout() the container here so that we know the number of actions
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // that will be visible in ShouldShow().
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  container_->Layout();
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If we were opened for a drop command, we have to wait for the drop to
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // finish so we can close the wrench menu.
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (wrench_menu_->for_drop()) {
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    browser_actions_container_observer_.Add(container_);
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    browser_actions_container_observer_.Add(main);
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
59116680a4aac90f2aa7413d9095a592090648e557Ben MurdochExtensionToolbarMenuView::~ExtensionToolbarMenuView() {
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ExtensionToolbarMenuView::ShouldShow() {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return wrench_menu_->for_drop() ||
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      container_->VisibleBrowserActionsAfterAnimation();
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochgfx::Size ExtensionToolbarMenuView::GetPreferredSize() const {
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return container_->GetPreferredSize();
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint ExtensionToolbarMenuView::GetHeightForWidth(int width) const {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const views::MenuConfig& menu_config =
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<const views::MenuItemView*>(parent())->GetMenuConfig();
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int end_padding = menu_config.arrow_to_edge_padding -
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    BrowserActionsContainer::kItemSpacing;
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  width -= start_padding() + end_padding;
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int height = container_->GetHeightForWidth(width);
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return height;
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionToolbarMenuView::Layout() {
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  gfx::Size sz = GetPreferredSize();
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetBounds(start_padding() + 1, 0, sz.width(), sz.height());
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  container_->SetBounds(0, 0, sz.width(), sz.height());
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ExtensionToolbarMenuView::OnBrowserActionDragDone() {
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The delay before we close the wrench menu if this was opened for a drop so
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // that the user can see a browser action if one was moved.
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static const int kCloseMenuDelay = 300;
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(wrench_menu_->for_drop());
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MessageLoop::current()->PostDelayedTask(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&ExtensionToolbarMenuView::CloseWrenchMenu,
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 weak_factory_.GetWeakPtr()),
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::TimeDelta::FromMilliseconds(kCloseMenuDelay));
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ExtensionToolbarMenuView::CloseWrenchMenu() {
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  wrench_menu_->CloseMenu();
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
104