Home | History | Annotate | Download | only in controls
      1 // Copyright (c) 2012 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 UI_VIEWS_CONTROLS_SCROLL_VIEW_H_
      6 #define UI_VIEWS_CONTROLS_SCROLL_VIEW_H_
      7 
      8 #include <string>
      9 
     10 #include "base/compiler_specific.h"
     11 #include "ui/views/controls/scrollbar/scroll_bar.h"
     12 
     13 namespace views {
     14 
     15 /////////////////////////////////////////////////////////////////////////////
     16 //
     17 // ScrollView class
     18 //
     19 // A ScrollView is used to make any View scrollable. The view is added to
     20 // a viewport which takes care of clipping.
     21 //
     22 // In this current implementation both horizontal and vertical scrollbars are
     23 // added as needed.
     24 //
     25 // The scrollview supports keyboard UI and mousewheel.
     26 //
     27 /////////////////////////////////////////////////////////////////////////////
     28 
     29 class VIEWS_EXPORT ScrollView : public View, public ScrollBarController {
     30  public:
     31   static const char kViewClassName[];
     32 
     33   ScrollView();
     34 
     35   virtual ~ScrollView();
     36 
     37   // Creates a ScrollView with a theme specific border.
     38   static ScrollView* CreateScrollViewWithBorder();
     39 
     40   // Set the contents. Any previous contents will be deleted. The contents
     41   // is the view that needs to scroll.
     42   void SetContents(View* a_view);
     43   const View* contents() const { return contents_; }
     44   View* contents() { return contents_; }
     45 
     46   // Sets the header, deleting the previous header.
     47   void SetHeader(View* header);
     48 
     49   // Returns the visible region of the content View.
     50   gfx::Rect GetVisibleRect() const;
     51 
     52   void set_hide_horizontal_scrollbar(bool visible) {
     53     hide_horizontal_scrollbar_ = visible;
     54   }
     55 
     56   // Turns this scroll view into a bounded scroll view, with a fixed height.
     57   // By default, a ScrollView will stretch to fill its outer container.
     58   void ClipHeightTo(int min_height, int max_height);
     59 
     60   // Returns whether or not the ScrollView is bounded (as set by ClipHeightTo).
     61   bool is_bounded() const { return max_height_ >= 0 && min_height_ >= 0; }
     62 
     63   // Retrieves the width/height of scrollbars. These return 0 if the scrollbar
     64   // has not yet been created.
     65   int GetScrollBarWidth() const;
     66   int GetScrollBarHeight() const;
     67 
     68   // Returns the horizontal/vertical scrollbar. This may return NULL.
     69   const ScrollBar* horizontal_scroll_bar() const { return horiz_sb_; }
     70   const ScrollBar* vertical_scroll_bar() const { return vert_sb_; }
     71 
     72   // Customize the scrollbar design. ScrollView takes the ownership of the
     73   // specified ScrollBar. |horiz_sb| and |vert_sb| cannot be NULL.
     74   void SetHorizontalScrollBar(ScrollBar* horiz_sb);
     75   void SetVerticalScrollBar(ScrollBar* vert_sb);
     76 
     77   // View overrides:
     78   virtual gfx::Size GetPreferredSize() const OVERRIDE;
     79   virtual int GetHeightForWidth(int width) const OVERRIDE;
     80   virtual void Layout() OVERRIDE;
     81   virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
     82   virtual bool OnMouseWheel(const ui::MouseWheelEvent& e) OVERRIDE;
     83   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
     84   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
     85   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
     86   virtual const char* GetClassName() const OVERRIDE;
     87 
     88   // ScrollBarController overrides:
     89   virtual void ScrollToPosition(ScrollBar* source, int position) OVERRIDE;
     90   virtual int GetScrollIncrement(ScrollBar* source,
     91                                  bool is_page,
     92                                  bool is_positive) OVERRIDE;
     93 
     94  private:
     95   FRIEND_TEST_ALL_PREFIXES(ScrollViewTest, CornerViewVisibility);
     96   class Viewport;
     97 
     98   // Used internally by SetHeader() and SetContents() to reset the view.  Sets
     99   // |member| to |new_view|. If |new_view| is non-null it is added to |parent|.
    100   void SetHeaderOrContents(View* parent, View* new_view, View** member);
    101 
    102   // Scrolls the minimum amount necessary to make the specified rectangle
    103   // visible, in the coordinates of the contents view. The specified rectangle
    104   // is constrained by the bounds of the contents view. This has no effect if
    105   // the contents have not been set.
    106   void ScrollContentsRegionToBeVisible(const gfx::Rect& rect);
    107 
    108   // Computes the visibility of both scrollbars, taking in account the view port
    109   // and content sizes.
    110   void ComputeScrollBarsVisibility(const gfx::Size& viewport_size,
    111                                    const gfx::Size& content_size,
    112                                    bool* horiz_is_shown,
    113                                    bool* vert_is_shown) const;
    114 
    115   // Shows or hides the scrollbar/corner_view based on the value of
    116   // |should_show|.
    117   void SetControlVisibility(View* control, bool should_show);
    118 
    119   // Update the scrollbars positions given viewport and content sizes.
    120   void UpdateScrollBarPositions();
    121 
    122   // The current contents and its viewport. |contents_| is contained in
    123   // |contents_viewport_|.
    124   View* contents_;
    125   View* contents_viewport_;
    126 
    127   // The current header and its viewport. |header_| is contained in
    128   // |header_viewport_|.
    129   View* header_;
    130   View* header_viewport_;
    131 
    132   // Horizontal scrollbar.
    133   ScrollBar* horiz_sb_;
    134 
    135   // Vertical scrollbar.
    136   ScrollBar* vert_sb_;
    137 
    138   // Corner view.
    139   View* corner_view_;
    140 
    141   // The min and max height for the bounded scroll view. These are negative
    142   // values if the view is not bounded.
    143   int min_height_;
    144   int max_height_;
    145 
    146   // If true, never show the horizontal scrollbar (even if the contents is wider
    147   // than the viewport).
    148   bool hide_horizontal_scrollbar_;
    149 
    150   DISALLOW_COPY_AND_ASSIGN(ScrollView);
    151 };
    152 
    153 // VariableRowHeightScrollHelper is intended for views that contain rows of
    154 // varying height. To use a VariableRowHeightScrollHelper create one supplying
    155 // a Controller and delegate GetPageScrollIncrement and GetLineScrollIncrement
    156 // to the helper. VariableRowHeightScrollHelper calls back to the
    157 // Controller to determine row boundaries.
    158 class VariableRowHeightScrollHelper {
    159  public:
    160   // The origin and height of a row.
    161   struct RowInfo {
    162     RowInfo(int origin, int height) : origin(origin), height(height) {}
    163 
    164     // Origin of the row.
    165     int origin;
    166 
    167     // Height of the row.
    168     int height;
    169   };
    170 
    171   // Used to determine row boundaries.
    172   class Controller {
    173    public:
    174     // Returns the origin and size of the row at the specified location.
    175     virtual VariableRowHeightScrollHelper::RowInfo GetRowInfo(int y) = 0;
    176   };
    177 
    178   // Creates a new VariableRowHeightScrollHelper. Controller is
    179   // NOT deleted by this VariableRowHeightScrollHelper.
    180   explicit VariableRowHeightScrollHelper(Controller* controller);
    181   virtual ~VariableRowHeightScrollHelper();
    182 
    183   // Delegate the View methods of the same name to these. The scroll amount is
    184   // determined by querying the Controller for the appropriate row to scroll
    185   // to.
    186   int GetPageScrollIncrement(ScrollView* scroll_view,
    187                              bool is_horizontal, bool is_positive);
    188   int GetLineScrollIncrement(ScrollView* scroll_view,
    189                              bool is_horizontal, bool is_positive);
    190 
    191  protected:
    192   // Returns the row information for the row at the specified location. This
    193   // calls through to the method of the same name on the controller.
    194   virtual RowInfo GetRowInfo(int y);
    195 
    196  private:
    197   Controller* controller_;
    198 
    199   DISALLOW_COPY_AND_ASSIGN(VariableRowHeightScrollHelper);
    200 };
    201 
    202 // FixedRowHeightScrollHelper is intended for views that contain fixed height
    203 // height rows. To use a FixedRowHeightScrollHelper delegate
    204 // GetPageScrollIncrement and GetLineScrollIncrement to it.
    205 class FixedRowHeightScrollHelper : public VariableRowHeightScrollHelper {
    206  public:
    207   // Creates a FixedRowHeightScrollHelper. top_margin gives the distance from
    208   // the top of the view to the first row, and may be 0. row_height gives the
    209   // height of each row.
    210   FixedRowHeightScrollHelper(int top_margin, int row_height);
    211 
    212  protected:
    213   // Calculates the bounds of the row from the top margin and row height.
    214   virtual RowInfo GetRowInfo(int y) OVERRIDE;
    215 
    216  private:
    217   int top_margin_;
    218   int row_height_;
    219 
    220   DISALLOW_COPY_AND_ASSIGN(FixedRowHeightScrollHelper);
    221 };
    222 
    223 }  // namespace views
    224 
    225 #endif  // UI_VIEWS_CONTROLS_SCROLL_VIEW_H_
    226