• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
contents()43   const View* contents() const { return contents_; }
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 
set_hide_horizontal_scrollbar(bool visible)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).
is_bounded()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.
horizontal_scroll_bar()69   const ScrollBar* horizontal_scroll_bar() const { return horiz_sb_; }
vertical_scroll_bar()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   class Viewport;
96 
97   // Used internally by SetHeader() and SetContents() to reset the view.  Sets
98   // |member| to |new_view|. If |new_view| is non-null it is added to |parent|.
99   void SetHeaderOrContents(View* parent, View* new_view, View** member);
100 
101   // Scrolls the minimum amount necessary to make the specified rectangle
102   // visible, in the coordinates of the contents view. The specified rectangle
103   // is constrained by the bounds of the contents view. This has no effect if
104   // the contents have not been set.
105   void ScrollContentsRegionToBeVisible(const gfx::Rect& rect);
106 
107   // Computes the visibility of both scrollbars, taking in account the view port
108   // and content sizes.
109   void ComputeScrollBarsVisibility(const gfx::Size& viewport_size,
110                                    const gfx::Size& content_size,
111                                    bool* horiz_is_shown,
112                                    bool* vert_is_shown) const;
113 
114   // Shows or hides the scrollbar/resize_corner based on the value of
115   // |should_show|.
116   void SetControlVisibility(View* control, bool should_show);
117 
118   // Update the scrollbars positions given viewport and content sizes.
119   void UpdateScrollBarPositions();
120 
121   // The current contents and its viewport. |contents_| is contained in
122   // |contents_viewport_|.
123   View* contents_;
124   View* contents_viewport_;
125 
126   // The current header and its viewport. |header_| is contained in
127   // |header_viewport_|.
128   View* header_;
129   View* header_viewport_;
130 
131   // Horizontal scrollbar.
132   ScrollBar* horiz_sb_;
133 
134   // Vertical scrollbar.
135   ScrollBar* vert_sb_;
136 
137   // Resize corner.
138   View* resize_corner_;
139 
140   // The min and max height for the bounded scroll view. These are negative
141   // values if the view is not bounded.
142   int min_height_;
143   int max_height_;
144 
145   // If true, never show the horizontal scrollbar (even if the contents is wider
146   // than the viewport).
147   bool hide_horizontal_scrollbar_;
148 
149   DISALLOW_COPY_AND_ASSIGN(ScrollView);
150 };
151 
152 // VariableRowHeightScrollHelper is intended for views that contain rows of
153 // varying height. To use a VariableRowHeightScrollHelper create one supplying
154 // a Controller and delegate GetPageScrollIncrement and GetLineScrollIncrement
155 // to the helper. VariableRowHeightScrollHelper calls back to the
156 // Controller to determine row boundaries.
157 class VariableRowHeightScrollHelper {
158  public:
159   // The origin and height of a row.
160   struct RowInfo {
RowInfoRowInfo161     RowInfo(int origin, int height) : origin(origin), height(height) {}
162 
163     // Origin of the row.
164     int origin;
165 
166     // Height of the row.
167     int height;
168   };
169 
170   // Used to determine row boundaries.
171   class Controller {
172    public:
173     // Returns the origin and size of the row at the specified location.
174     virtual VariableRowHeightScrollHelper::RowInfo GetRowInfo(int y) = 0;
175   };
176 
177   // Creates a new VariableRowHeightScrollHelper. Controller is
178   // NOT deleted by this VariableRowHeightScrollHelper.
179   explicit VariableRowHeightScrollHelper(Controller* controller);
180   virtual ~VariableRowHeightScrollHelper();
181 
182   // Delegate the View methods of the same name to these. The scroll amount is
183   // determined by querying the Controller for the appropriate row to scroll
184   // to.
185   int GetPageScrollIncrement(ScrollView* scroll_view,
186                              bool is_horizontal, bool is_positive);
187   int GetLineScrollIncrement(ScrollView* scroll_view,
188                              bool is_horizontal, bool is_positive);
189 
190  protected:
191   // Returns the row information for the row at the specified location. This
192   // calls through to the method of the same name on the controller.
193   virtual RowInfo GetRowInfo(int y);
194 
195  private:
196   Controller* controller_;
197 
198   DISALLOW_COPY_AND_ASSIGN(VariableRowHeightScrollHelper);
199 };
200 
201 // FixedRowHeightScrollHelper is intended for views that contain fixed height
202 // height rows. To use a FixedRowHeightScrollHelper delegate
203 // GetPageScrollIncrement and GetLineScrollIncrement to it.
204 class FixedRowHeightScrollHelper : public VariableRowHeightScrollHelper {
205  public:
206   // Creates a FixedRowHeightScrollHelper. top_margin gives the distance from
207   // the top of the view to the first row, and may be 0. row_height gives the
208   // height of each row.
209   FixedRowHeightScrollHelper(int top_margin, int row_height);
210 
211  protected:
212   // Calculates the bounds of the row from the top margin and row height.
213   virtual RowInfo GetRowInfo(int y) OVERRIDE;
214 
215  private:
216   int top_margin_;
217   int row_height_;
218 
219   DISALLOW_COPY_AND_ASSIGN(FixedRowHeightScrollHelper);
220 };
221 
222 }  // namespace views
223 
224 #endif  // UI_VIEWS_CONTROLS_SCROLL_VIEW_H_
225