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