dropdown_bar_host.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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
16class BrowserView;
17class DropdownBarHostDelegate;
18class DropdownBarView;
19
20namespace content {
21class WebContents;
22}
23
24namespace gfx {
25class SlideAnimation;
26}  // namespace gfx
27
28namespace views {
29class ExternalFocusTracker;
30class View;
31class 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////////////////////////////////////////////////////////////////////////////////
43class 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