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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_ 6 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_ 7 8 #include "chrome/browser/ui/views/extensions/extension_action_view_controller.h" 9 #include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h" 10 #include "content/public/browser/notification_observer.h" 11 #include "content/public/browser/notification_registrar.h" 12 #include "ui/views/controls/button/menu_button.h" 13 #include "ui/views/controls/button/menu_button_listener.h" 14 #include "ui/views/drag_controller.h" 15 #include "ui/views/view.h" 16 17 class Browser; 18 class ExtensionAction; 19 20 namespace extensions { 21 class Extension; 22 } 23 24 namespace gfx { 25 class Image; 26 } 27 28 //////////////////////////////////////////////////////////////////////////////// 29 // BrowserActionView 30 // A wrapper around an ExtensionActionViewController to display an extension 31 // action in the BrowserActionsContainer. 32 // Despite its name, this class can handle either Browser Actions or Page 33 // Actions. 34 // TODO(devlin): Rename this and BrowserActionsContainer when more of the 35 // toolbar redesign is done. 36 class BrowserActionView : public views::MenuButton, 37 public ExtensionActionViewDelegate, 38 public views::ButtonListener, 39 public content::NotificationObserver { 40 public: 41 // Need DragController here because BrowserActionView could be 42 // dragged/dropped. 43 class Delegate : public views::DragController { 44 public: 45 // Returns the current web contents. 46 virtual content::WebContents* GetCurrentWebContents() = 0; 47 48 // Whether the container for this button is shown inside a menu. 49 virtual bool ShownInsideMenu() const = 0; 50 51 // Notifies that a drag completed. Note this will only happen if the view 52 // wasn't removed during the drag-and-drop process (i.e., not when there 53 // was a move in the browser actions, since we re-create the views each 54 // time we re-order the browser actions). 55 virtual void OnBrowserActionViewDragDone() = 0; 56 57 // Returns the view of the browser actions overflow menu to use as a 58 // reference point for a popup when this view isn't visible. 59 virtual views::MenuButton* GetOverflowReferenceView() = 0; 60 61 // Sets the delegate's active popup owner to be |popup_owner|. 62 virtual void SetPopupOwner(BrowserActionView* popup_owner) = 0; 63 64 // Hides the active popup of the delegate, if one exists. 65 virtual void HideActivePopup() = 0; 66 67 // Returns the primary BrowserActionView associated with the given 68 // |extension|. 69 virtual BrowserActionView* GetMainViewForExtension( 70 const extensions::Extension* extension) = 0; 71 72 protected: 73 virtual ~Delegate() {} 74 }; 75 76 // The IconObserver will receive a notification when the button's icon has 77 // been updated. 78 class IconObserver { 79 public: 80 virtual void OnIconUpdated(const gfx::ImageSkia& icon) = 0; 81 82 protected: 83 virtual ~IconObserver() {} 84 }; 85 86 BrowserActionView(const extensions::Extension* extension, 87 ExtensionAction* extension_action, 88 Browser* browser, 89 BrowserActionView::Delegate* delegate); 90 virtual ~BrowserActionView(); 91 92 const extensions::Extension* extension() const { 93 return view_controller_->extension(); 94 } 95 ExtensionAction* extension_action() { 96 return view_controller_->extension_action(); 97 } 98 ExtensionActionViewController* view_controller() { 99 return view_controller_.get(); 100 } 101 void set_icon_observer(IconObserver* icon_observer) { 102 icon_observer_ = icon_observer; 103 } 104 105 // Called to update the display to match the browser action's state. 106 void UpdateState(); 107 108 // Does this button's action have a popup? 109 bool IsPopup(); 110 111 // Overridden from views::View: 112 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 113 114 // Overridden from views::ButtonListener: 115 virtual void ButtonPressed(views::Button* sender, 116 const ui::Event& event) OVERRIDE; 117 118 // Overridden from content::NotificationObserver: 119 virtual void Observe(int type, 120 const content::NotificationSource& source, 121 const content::NotificationDetails& details) OVERRIDE; 122 123 // MenuButton behavior overrides. These methods all default to LabelButton 124 // behavior unless this button is a popup. In that case, it uses MenuButton 125 // behavior. MenuButton has the notion of a child popup being shown where the 126 // button will stay in the pushed state until the "menu" (a popup in this 127 // case) is dismissed. 128 virtual bool Activate() OVERRIDE; 129 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 130 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 131 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 132 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE; 133 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 134 virtual scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const 135 OVERRIDE; 136 137 // Whether the browser action is enabled on this tab. Note that we cannot use 138 // the built-in views enabled/SetEnabled because disabled views do not 139 // receive drag events. 140 bool IsEnabled(int tab_id) const; 141 142 // Gets the icon of this button and its badge. 143 gfx::ImageSkia GetIconWithBadge(); 144 145 // Returns button icon so it can be accessed during tests. 146 gfx::ImageSkia GetIconForTest(); 147 148 private: 149 // Overridden from views::View: 150 virtual void ViewHierarchyChanged( 151 const ViewHierarchyChangedDetails& details) OVERRIDE; 152 virtual void OnDragDone() OVERRIDE; 153 virtual gfx::Size GetPreferredSize() const OVERRIDE; 154 virtual void PaintChildren(gfx::Canvas* canvas, 155 const views::CullSet& cull_set) OVERRIDE; 156 157 // ExtensionActionViewDelegate: 158 virtual views::View* GetAsView() OVERRIDE; 159 virtual bool IsShownInMenu() OVERRIDE; 160 virtual views::FocusManager* GetFocusManagerForAccelerator() OVERRIDE; 161 virtual views::Widget* GetParentForContextMenu() OVERRIDE; 162 virtual ExtensionActionViewController* GetPreferredPopupViewController() 163 OVERRIDE; 164 virtual views::View* GetReferenceViewForPopup() OVERRIDE; 165 virtual views::MenuButton* GetContextMenuButton() OVERRIDE; 166 virtual content::WebContents* GetCurrentWebContents() OVERRIDE; 167 virtual void HideActivePopup() OVERRIDE; 168 virtual void OnIconUpdated() OVERRIDE; 169 virtual void OnPopupShown(bool grant_tab_permissions) OVERRIDE; 170 virtual void CleanupPopup() OVERRIDE; 171 172 // The controller for this ExtensionAction view. 173 scoped_ptr<ExtensionActionViewController> view_controller_; 174 175 // Delegate that usually represents a container for BrowserActionView. 176 BrowserActionView::Delegate* delegate_; 177 178 // Used to make sure we only register the command once. 179 bool called_registered_extension_command_; 180 181 content::NotificationRegistrar registrar_; 182 183 // The observer that we need to notify when the icon of the button has been 184 // updated. 185 IconObserver* icon_observer_; 186 187 // A lock to keep the MenuButton pressed when a menu or popup is visible. 188 scoped_ptr<views::MenuButton::PressedLock> pressed_lock_; 189 190 DISALLOW_COPY_AND_ASSIGN(BrowserActionView); 191 }; 192 193 #endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_ 194