Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2011 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_DROPDOWN_BAR_HOST_H_
      6 #define CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_H_
      7 
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "content/public/browser/native_web_keyboard_event.h"
     11 #include "ui/gfx/animation/animation_delegate.h"
     12 #include "ui/gfx/native_widget_types.h"
     13 #include "ui/gfx/rect.h"
     14 #include "ui/views/focus/focus_manager.h"
     15 
     16 class BrowserView;
     17 class DropdownBarHostDelegate;
     18 class DropdownBarView;
     19 
     20 namespace content {
     21 class WebContents;
     22 }
     23 
     24 namespace gfx {
     25 class SlideAnimation;
     26 }  // namespace gfx
     27 
     28 namespace views {
     29 class ExternalFocusTracker;
     30 class View;
     31 class Widget;
     32 }  // namespace views
     33 
     34 ////////////////////////////////////////////////////////////////////////////////
     35 //
     36 // The DropdownBarHost implements the container widget for the UI that
     37 // is shown at the top of browser contents. It uses the implementation from
     38 // dropdown_bar_host_aura.cc to draw its content and is responsible for showing,
     39 // hiding, animating, closing, and moving the bar if needed, for example if the
     40 // widget is obscuring the selection results in FindBar.
     41 //
     42 ////////////////////////////////////////////////////////////////////////////////
     43 class DropdownBarHost : public ui::AcceleratorTarget,
     44                         public views::FocusChangeListener,
     45                         public gfx::AnimationDelegate {
     46  public:
     47   explicit DropdownBarHost(BrowserView* browser_view);
     48   virtual ~DropdownBarHost();
     49 
     50   // Initializes the DropdownBarHost. This creates the widget that |view| paints
     51   // into.
     52   // |host_view| is the view whose position in the |browser_view_| view
     53   // hierarchy determines the z-order of the widget relative to views with
     54   // layers and views with associated NativeViews.
     55   void Init(views::View* host_view,
     56             views::View* view,
     57             DropdownBarHostDelegate* delegate);
     58 
     59   // Whether we are animating the position of the dropdown widget.
     60   bool IsAnimating() const;
     61   // Returns true if the dropdown bar view is visible, or false otherwise.
     62   bool IsVisible() const;
     63   // Selects text in the entry field and set focus.
     64   void SetFocusAndSelection();
     65   // Stops the animation.
     66   void StopAnimation();
     67 
     68   // Shows the dropdown bar.
     69   virtual void Show(bool animate);
     70   // Hides the dropdown bar.
     71   virtual void Hide(bool animate);
     72 
     73   // Returns the rectangle representing where to position the dropdown widget.
     74   virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect) = 0;
     75 
     76   // Moves the widget to the provided location, moves it to top
     77   // in the z-order (HWND_TOP, not HWND_TOPMOST for windows) and shows
     78   // the widget (if hidden).
     79   virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) = 0;
     80 
     81   // Overridden from views::FocusChangeListener:
     82   virtual void OnWillChangeFocus(views::View* focused_before,
     83                                  views::View* focused_now) OVERRIDE;
     84   virtual void OnDidChangeFocus(views::View* focused_before,
     85                                 views::View* focused_now) OVERRIDE;
     86 
     87   // Overridden from ui::AcceleratorTarget:
     88   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) = 0;
     89   virtual bool CanHandleAccelerators() const = 0;
     90 
     91   // gfx::AnimationDelegate implementation:
     92   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
     93   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
     94 
     95   // During testing we can disable animations by setting this flag to true,
     96   // so that opening and closing the dropdown bar is shown instantly, instead of
     97   // having to poll it while it animates to open/closed status.
     98   static bool disable_animations_during_testing_;
     99 
    100   // Returns the browser view that the dropdown belongs to.
    101   BrowserView* browser_view() const { return browser_view_; }
    102 
    103   // Registers this class as the handler for when Escape is pressed. Once we
    104   // loose focus we will unregister Escape and (any accelerators the derived
    105   // classes registers by using overrides of RegisterAccelerators). See also:
    106   // SetFocusChangeListener().
    107   virtual void RegisterAccelerators();
    108 
    109   // When we loose focus, we unregister all accelerator handlers. See also:
    110   // SetFocusChangeListener().
    111   virtual void UnregisterAccelerators();
    112 
    113  protected:
    114   // Called when the drop down bar visibility, aka the value of IsVisible(),
    115   // changes.
    116   virtual void OnVisibilityChanged();
    117 
    118   // Returns the dropdown bar view.
    119   views::View* view() const { return view_; }
    120 
    121   // Returns the focus tracker.
    122   views::ExternalFocusTracker* focus_tracker() const {
    123     return focus_tracker_.get();
    124   }
    125 
    126   // Resets the focus tracker.
    127   void ResetFocusTracker();
    128 
    129   // The focus manager we register with to keep track of focus changes.
    130   views::FocusManager* focus_manager() const { return focus_manager_; }
    131 
    132   // Returns the host widget.
    133   views::Widget* host() const { return host_.get(); }
    134 
    135   // Returns the animation offset.
    136   int animation_offset() const { return animation_offset_; }
    137 
    138   // Retrieves the boundary that the dropdown widget has to work with
    139   // within the Chrome frame window. The boundary differs depending on
    140   // the dropdown bar implementation. The default implementation
    141   // returns the boundary of browser_view and the drop down
    142   // can be shown in any client area.
    143   virtual void GetWidgetBounds(gfx::Rect* bounds);
    144 
    145   // Allows implementation to tweak widget position.
    146   void SetWidgetPositionNative(const gfx::Rect& new_pos, bool no_redraw);
    147 
    148   // Returns a keyboard event suitable for forwarding.
    149   content::NativeWebKeyboardEvent GetKeyboardEvent(
    150       const content::WebContents* contents,
    151       const ui::KeyEvent& key_event);
    152 
    153   // Returns the animation for the dropdown.
    154   gfx::SlideAnimation* animation() {
    155     return animation_.get();
    156   }
    157 
    158  private:
    159   // Set the view whose position in the |browser_view_| view hierarchy
    160   // determines the z-order of |host_| relative to views with layers and
    161   // views with associated NativeViews.
    162   void SetHostViewNative(views::View* host_view);
    163 
    164   // The BrowserView that created us.
    165   BrowserView* browser_view_;
    166 
    167   // Our view, which is responsible for drawing the UI.
    168   views::View* view_;
    169   DropdownBarHostDelegate* delegate_;
    170 
    171   // The y position pixel offset of the widget while animating the
    172   // dropdown widget.
    173   int animation_offset_;
    174 
    175   // The animation class to use when opening the Dropdown widget.
    176   scoped_ptr<gfx::SlideAnimation> animation_;
    177 
    178   // The focus manager we register with to keep track of focus changes.
    179   views::FocusManager* focus_manager_;
    180 
    181   // True if the accelerator target for Esc key is registered.
    182   bool esc_accel_target_registered_;
    183 
    184   // Tracks and stores the last focused view which is not the DropdownBarView
    185   // or any of its children. Used to restore focus once the DropdownBarView is
    186   // closed.
    187   scoped_ptr<views::ExternalFocusTracker> focus_tracker_;
    188 
    189   // Host is the Widget implementation that is created and maintained by the
    190   // dropdown bar. It contains the DropdownBarView.
    191   scoped_ptr<views::Widget> host_;
    192 
    193   // A flag to manually manage visibility. GTK/X11 is asynchronous and
    194   // the state of the widget can be out of sync.
    195   bool is_visible_;
    196 
    197   DISALLOW_COPY_AND_ASSIGN(DropdownBarHost);
    198 };
    199 
    200 #endif  // CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_H_
    201