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