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