Home | History | Annotate | Download | only in toolbar
      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