dropdown_bar_host.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 // The find bar widget needs rounded edges, so we create a polygon 146 // that corresponds to the background images for this window (and 147 // make the polygon only contain the pixels that we want to 148 // draw). The polygon is then given to SetWindowRgn which changes 149 // the window from being a rectangle in shape, to being a rect with 150 // curved edges. We also check to see if the region should be 151 // truncated to prevent from drawing onto Chrome's window border. 152 void UpdateWindowEdges(const gfx::Rect& new_pos); 153 154 // Allows implementation to tweak widget position. 155 void SetWidgetPositionNative(const gfx::Rect& new_pos, bool no_redraw); 156 157 // Returns a keyboard event suitable for forwarding. 158 content::NativeWebKeyboardEvent GetKeyboardEvent( 159 const content::WebContents* contents, 160 const ui::KeyEvent& key_event); 161 162 // Returns the animation for the dropdown. 163 gfx::SlideAnimation* animation() { 164 return animation_.get(); 165 } 166 167 private: 168 // Set the view whose position in the |browser_view_| view hierarchy 169 // determines the z-order of |host_| relative to views with layers and 170 // views with associated NativeViews. 171 void SetHostViewNative(views::View* host_view); 172 173 // The BrowserView that created us. 174 BrowserView* browser_view_; 175 176 // Our view, which is responsible for drawing the UI. 177 views::View* view_; 178 DropdownBarHostDelegate* delegate_; 179 180 // The y position pixel offset of the widget while animating the 181 // dropdown widget. 182 int animation_offset_; 183 184 // The animation class to use when opening the Dropdown widget. 185 scoped_ptr<gfx::SlideAnimation> animation_; 186 187 // The focus manager we register with to keep track of focus changes. 188 views::FocusManager* focus_manager_; 189 190 // True if the accelerator target for Esc key is registered. 191 bool esc_accel_target_registered_; 192 193 // Tracks and stores the last focused view which is not the DropdownBarView 194 // or any of its children. Used to restore focus once the DropdownBarView is 195 // closed. 196 scoped_ptr<views::ExternalFocusTracker> focus_tracker_; 197 198 // Host is the Widget implementation that is created and maintained by the 199 // dropdown bar. It contains the DropdownBarView. 200 scoped_ptr<views::Widget> host_; 201 202 // A flag to manually manage visibility. GTK/X11 is asynchronous and 203 // the state of the widget can be out of sync. 204 bool is_visible_; 205 206 DISALLOW_COPY_AND_ASSIGN(DropdownBarHost); 207}; 208 209#endif // CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_H_ 210