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 virtual ~ScrollView(); 35 36 // Creates a ScrollView with a theme specific border. 37 static ScrollView* CreateScrollViewWithBorder(); 38 39 // Set the contents. Any previous contents will be deleted. The contents 40 // is the view that needs to scroll. 41 void SetContents(View* a_view); 42 const View* contents() const { return contents_; } 43 View* contents() { return contents_; } 44 45 // Sets the header, deleting the previous header. 46 void SetHeader(View* header); 47 48 // Returns the visible region of the content View. 49 gfx::Rect GetVisibleRect() const; 50 51 void set_hide_horizontal_scrollbar(bool visible) { 52 hide_horizontal_scrollbar_ = visible; 53 } 54 55 // Retrieves the width/height of scrollbars. These return 0 if the scrollbar 56 // has not yet been created. 57 int GetScrollBarWidth() const; 58 int GetScrollBarHeight() const; 59 60 // Returns the horizontal/vertical scrollbar. This may return NULL. 61 const ScrollBar* horizontal_scroll_bar() const { return horiz_sb_; } 62 const ScrollBar* vertical_scroll_bar() const { return vert_sb_; } 63 64 // Customize the scrollbar design. ScrollView takes the ownership of the 65 // specified ScrollBar. |horiz_sb| and |vert_sb| cannot be NULL. 66 void SetHorizontalScrollBar(ScrollBar* horiz_sb); 67 void SetVerticalScrollBar(ScrollBar* vert_sb); 68 69 // View overrides: 70 virtual void Layout() OVERRIDE; 71 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 72 virtual bool OnMouseWheel(const ui::MouseWheelEvent& e) OVERRIDE; 73 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 74 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 75 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 76 virtual const char* GetClassName() const OVERRIDE; 77 78 // ScrollBarController overrides: 79 virtual void ScrollToPosition(ScrollBar* source, int position) OVERRIDE; 80 virtual int GetScrollIncrement(ScrollBar* source, 81 bool is_page, 82 bool is_positive) OVERRIDE; 83 84 private: 85 class Viewport; 86 87 // Used internally by SetHeader() and SetContents() to reset the view. Sets 88 // |member| to |new_view|. If |new_view| is non-null it is added to |parent|. 89 void SetHeaderOrContents(View* parent, View* new_view, View** member); 90 91 // Scrolls the minimum amount necessary to make the specified rectangle 92 // visible, in the coordinates of the contents view. The specified rectangle 93 // is constrained by the bounds of the contents view. This has no effect if 94 // the contents have not been set. 95 void ScrollContentsRegionToBeVisible(const gfx::Rect& rect); 96 97 // Computes the visibility of both scrollbars, taking in account the view port 98 // and content sizes. 99 void ComputeScrollBarsVisibility(const gfx::Size& viewport_size, 100 const gfx::Size& content_size, 101 bool* horiz_is_shown, 102 bool* vert_is_shown) const; 103 104 // Shows or hides the scrollbar/resize_corner based on the value of 105 // |should_show|. 106 void SetControlVisibility(View* control, bool should_show); 107 108 // Update the scrollbars positions given viewport and content sizes. 109 void UpdateScrollBarPositions(); 110 111 // The current contents and its viewport. |contents_| is contained in 112 // |contents_viewport_|. 113 View* contents_; 114 View* contents_viewport_; 115 116 // The current header and its viewport. |header_| is contained in 117 // |header_viewport_|. 118 View* header_; 119 View* header_viewport_; 120 121 // Horizontal scrollbar. 122 ScrollBar* horiz_sb_; 123 124 // Vertical scrollbar. 125 ScrollBar* vert_sb_; 126 127 // Resize corner. 128 View* resize_corner_; 129 130 // If true, never show the horizontal scrollbar (even if the contents is wider 131 // than the viewport). 132 bool hide_horizontal_scrollbar_; 133 134 DISALLOW_COPY_AND_ASSIGN(ScrollView); 135 }; 136 137 // VariableRowHeightScrollHelper is intended for views that contain rows of 138 // varying height. To use a VariableRowHeightScrollHelper create one supplying 139 // a Controller and delegate GetPageScrollIncrement and GetLineScrollIncrement 140 // to the helper. VariableRowHeightScrollHelper calls back to the 141 // Controller to determine row boundaries. 142 class VariableRowHeightScrollHelper { 143 public: 144 // The origin and height of a row. 145 struct RowInfo { 146 RowInfo(int origin, int height) : origin(origin), height(height) {} 147 148 // Origin of the row. 149 int origin; 150 151 // Height of the row. 152 int height; 153 }; 154 155 // Used to determine row boundaries. 156 class Controller { 157 public: 158 // Returns the origin and size of the row at the specified location. 159 virtual VariableRowHeightScrollHelper::RowInfo GetRowInfo(int y) = 0; 160 }; 161 162 // Creates a new VariableRowHeightScrollHelper. Controller is 163 // NOT deleted by this VariableRowHeightScrollHelper. 164 explicit VariableRowHeightScrollHelper(Controller* controller); 165 virtual ~VariableRowHeightScrollHelper(); 166 167 // Delegate the View methods of the same name to these. The scroll amount is 168 // determined by querying the Controller for the appropriate row to scroll 169 // to. 170 int GetPageScrollIncrement(ScrollView* scroll_view, 171 bool is_horizontal, bool is_positive); 172 int GetLineScrollIncrement(ScrollView* scroll_view, 173 bool is_horizontal, bool is_positive); 174 175 protected: 176 // Returns the row information for the row at the specified location. This 177 // calls through to the method of the same name on the controller. 178 virtual RowInfo GetRowInfo(int y); 179 180 private: 181 Controller* controller_; 182 183 DISALLOW_COPY_AND_ASSIGN(VariableRowHeightScrollHelper); 184 }; 185 186 // FixedRowHeightScrollHelper is intended for views that contain fixed height 187 // height rows. To use a FixedRowHeightScrollHelper delegate 188 // GetPageScrollIncrement and GetLineScrollIncrement to it. 189 class FixedRowHeightScrollHelper : public VariableRowHeightScrollHelper { 190 public: 191 // Creates a FixedRowHeightScrollHelper. top_margin gives the distance from 192 // the top of the view to the first row, and may be 0. row_height gives the 193 // height of each row. 194 FixedRowHeightScrollHelper(int top_margin, int row_height); 195 196 protected: 197 // Calculates the bounds of the row from the top margin and row height. 198 virtual RowInfo GetRowInfo(int y) OVERRIDE; 199 200 private: 201 int top_margin_; 202 int row_height_; 203 204 DISALLOW_COPY_AND_ASSIGN(FixedRowHeightScrollHelper); 205 }; 206 207 } // namespace views 208 209 #endif // UI_VIEWS_CONTROLS_SCROLL_VIEW_H_ 210