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_SCROLLBAR_BASE_SCROLL_BAR_H_ 6 #define UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "ui/views/animation/scroll_animator.h" 10 #include "ui/views/context_menu_controller.h" 11 #include "ui/views/controls/button/image_button.h" 12 #include "ui/views/controls/menu/menu_delegate.h" 13 #include "ui/views/controls/scrollbar/scroll_bar.h" 14 #include "ui/views/repeat_controller.h" 15 16 namespace views { 17 18 class BaseScrollBarThumb; 19 class MenuRunner; 20 21 /////////////////////////////////////////////////////////////////////////////// 22 // 23 // BaseScrollBar 24 // 25 /////////////////////////////////////////////////////////////////////////////// 26 class VIEWS_EXPORT BaseScrollBar : public ScrollBar, 27 public ScrollDelegate, 28 public ContextMenuController, 29 public MenuDelegate { 30 public: 31 BaseScrollBar(bool horizontal, BaseScrollBarThumb* thumb); 32 virtual ~BaseScrollBar(); 33 34 // Get the bounds of the "track" area that the thumb is free to slide within. 35 virtual gfx::Rect GetTrackBounds() const = 0; 36 37 // An enumeration of different amounts of incremental scroll, representing 38 // events sent from different parts of the UI/keyboard. 39 enum ScrollAmount { 40 SCROLL_NONE = 0, 41 SCROLL_START, 42 SCROLL_END, 43 SCROLL_PREV_LINE, 44 SCROLL_NEXT_LINE, 45 SCROLL_PREV_PAGE, 46 SCROLL_NEXT_PAGE, 47 }; 48 49 // Scroll the contents by the specified type (see ScrollAmount above). 50 void ScrollByAmount(ScrollAmount amount); 51 52 // Scroll the contents to the appropriate position given the supplied 53 // position of the thumb (thumb track coordinates). If |scroll_to_middle| is 54 // true, then the conversion assumes |thumb_position| is in the middle of the 55 // thumb rather than the top. 56 void ScrollToThumbPosition(int thumb_position, bool scroll_to_middle); 57 58 // Scroll the contents by the specified offset (contents coordinates). 59 bool ScrollByContentsOffset(int contents_offset); 60 61 // Called when the thumb state has been changed from |old_state| to 62 // |new_state|. 63 void OnThumbStateChanged(CustomButton::ButtonState old_state, 64 CustomButton::ButtonState new_state); 65 66 // View overrides: 67 virtual gfx::Size GetPreferredSize() const OVERRIDE = 0; 68 virtual void Layout() OVERRIDE = 0; 69 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 70 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 71 virtual void OnMouseCaptureLost() OVERRIDE; 72 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 73 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 74 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 75 virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE; 76 77 // ui::EventHandler overrides: 78 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 79 80 // ScrollBar overrides: 81 virtual void Update(int viewport_size, 82 int content_size, 83 int contents_scroll_offset) OVERRIDE; 84 virtual int GetLayoutSize() const OVERRIDE = 0; 85 virtual int GetPosition() const OVERRIDE; 86 87 // ScrollDelegate overrides: 88 virtual bool OnScroll(float dx, float dy) OVERRIDE; 89 90 // ContextMenuController overrides: 91 virtual void ShowContextMenuForView(View* source, 92 const gfx::Point& point, 93 ui::MenuSourceType source_type) OVERRIDE; 94 95 // Menu::Delegate overrides: 96 virtual base::string16 GetLabel(int id) const OVERRIDE; 97 virtual bool IsCommandEnabled(int id) const OVERRIDE; 98 virtual void ExecuteCommand(int id) OVERRIDE; 99 100 protected: 101 // View overrides: 102 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE = 0; 103 104 BaseScrollBarThumb* GetThumb() const; 105 CustomButton::ButtonState GetThumbTrackState() const; 106 107 // Wrapper functions that calls the controller. We need this since native 108 // scrollbars wrap around a different scrollbar. When calling the controller 109 // we need to pass in the appropriate scrollbar. For normal scrollbars it's 110 // the |this| scrollbar, for native scrollbars it's the native scrollbar used 111 // to create this. 112 virtual void ScrollToPosition(int position); 113 virtual int GetScrollIncrement(bool is_page, bool is_positive); 114 115 private: 116 FRIEND_TEST_ALL_PREFIXES(NativeScrollBarTest, ScrollBarFitsToBottom); 117 int GetThumbSizeForTest(); 118 119 // Changes to 'pushed' state and starts a timer to scroll repeatedly. 120 void ProcessPressEvent(const ui::LocatedEvent& event); 121 122 // Sets state to |state| and stops the repeater. 123 void SetState(CustomButton::ButtonState state); 124 125 // Called when the mouse is pressed down in the track area. 126 void TrackClicked(); 127 128 // Responsible for scrolling the contents and also updating the UI to the 129 // current value of the Scroll Offset. 130 void ScrollContentsToOffset(); 131 132 // Returns the size (width or height) of the track area of the ScrollBar. 133 int GetTrackSize() const; 134 135 // Calculate the position of the thumb within the track based on the 136 // specified scroll offset of the contents. 137 int CalculateThumbPosition(int contents_scroll_offset) const; 138 139 // Calculates the current value of the contents offset (contents coordinates) 140 // based on the current thumb position (thumb track coordinates). See 141 // |ScrollToThumbPosition| for an explanation of |scroll_to_middle|. 142 int CalculateContentsOffset(int thumb_position, 143 bool scroll_to_middle) const; 144 145 // Called when the state of the thumb track changes (e.g. by the user 146 // pressing the mouse button down in it). 147 void SetThumbTrackState(CustomButton::ButtonState state); 148 149 BaseScrollBarThumb* thumb_; 150 151 // The size of the scrolled contents, in pixels. 152 int contents_size_; 153 154 // The current amount the contents is offset by in the viewport. 155 int contents_scroll_offset_; 156 157 // The current size of the view port, in pixels. 158 int viewport_size_; 159 160 // The state of the scrollbar track. Typically, the track will highlight when 161 // the user presses the mouse on them (during page scrolling). 162 CustomButton::ButtonState thumb_track_state_; 163 164 // The last amount of incremental scroll that this scrollbar performed. This 165 // is accessed by the callbacks for the auto-repeat up/down buttons to know 166 // what direction to repeatedly scroll in. 167 ScrollAmount last_scroll_amount_; 168 169 // An instance of a RepeatController which scrolls the scrollbar continuously 170 // as the user presses the mouse button down on the up/down buttons or the 171 // track. 172 RepeatController repeater_; 173 174 // The position of the mouse within the scroll bar when the context menu 175 // was invoked. 176 int context_menu_mouse_position_; 177 178 scoped_ptr<MenuRunner> menu_runner_; 179 scoped_ptr<ScrollAnimator> scroll_animator_; 180 181 // Difference between current position and cumulative deltas obtained from 182 // scroll update events. 183 // TODO(tdresser): This should be removed when raw pixel scrolling for views 184 // is enabled. See crbug.com/329354. 185 gfx::Vector2dF roundoff_error_; 186 187 DISALLOW_COPY_AND_ASSIGN(BaseScrollBar); 188 }; 189 190 } // namespace views 191 192 #endif // UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_ 193