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 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 { RowInfoRowInfo162 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