Home | History | Annotate | Download | only in views
      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