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