• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
browser_view()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.
view()119   views::View* view() const { return view_; }
120 
121   // Returns the focus tracker.
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.
focus_manager()130   views::FocusManager* focus_manager() const { return focus_manager_; }
131 
132   // Returns the host widget.
host()133   views::Widget* host() const { return host_.get(); }
134 
135   // Returns the animation offset.
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.
animation()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