15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/gtest_prod_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/animation/scroll_animator.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/context_menu_controller.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_delegate.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/scrollbar/scroll_bar.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/repeat_controller.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BaseScrollBarThumb; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MenuRunner; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BaseScrollBar 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VIEWS_EXPORT BaseScrollBar : public ScrollBar, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ScrollDelegate, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ContextMenuController, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public MenuDelegate { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseScrollBar(bool horizontal, BaseScrollBarThumb* thumb); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BaseScrollBar(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the bounds of the "track" area that the thumb is free to slide within. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Rect GetTrackBounds() const = 0; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An enumeration of different amounts of incremental scroll, representing 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events sent from different parts of the UI/keyboard. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ScrollAmount { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_NONE = 0, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_START, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_END, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_PREV_LINE, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_NEXT_LINE, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_PREV_PAGE, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCROLL_NEXT_PAGE, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scroll the contents by the specified type (see ScrollAmount above). 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScrollByAmount(ScrollAmount amount); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scroll the contents to the appropriate position given the supplied 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position of the thumb (thumb track coordinates). If |scroll_to_middle| is 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true, then the conversion assumes |thumb_position| is in the middle of the 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thumb rather than the top. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScrollToThumbPosition(int thumb_position, bool scroll_to_middle); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scroll the contents by the specified offset (contents coordinates). 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ScrollByContentsOffset(int contents_offset); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called when the thumb state has been changed from |old_state| to 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |new_state|. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnThumbStateChanged(CustomButton::ButtonState old_state, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CustomButton::ButtonState new_state); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // View overrides: 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE = 0; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Layout() OVERRIDE = 0; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMouseCaptureLost() OVERRIDE; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::EventHandler overrides: 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ScrollBar overrides: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Update(int viewport_size, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int content_size, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int contents_scroll_offset) OVERRIDE; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetLayoutSize() const OVERRIDE = 0; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetPosition() const OVERRIDE; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ScrollDelegate overrides: 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnScroll(float dx, float dy) OVERRIDE; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ContextMenuController overrides: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ShowContextMenuForView(View* source, 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gfx::Point& point, 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::MenuSourceType source_type) OVERRIDE; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Menu::Delegate overrides: 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::string16 GetLabel(int id) const OVERRIDE; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandEnabled(int id) const OVERRIDE; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ExecuteCommand(int id) OVERRIDE; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // View overrides: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseScrollBarThumb* GetThumb() const; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CustomButton::ButtonState GetThumbTrackState() const; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrapper functions that calls the controller. We need this since native 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scrollbars wrap around a different scrollbar. When calling the controller 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we need to pass in the appropriate scrollbar. For normal scrollbars it's 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the |this| scrollbar, for native scrollbars it's the native scrollbar used 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to create this. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ScrollToPosition(int position); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetScrollIncrement(bool is_page, bool is_positive); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(NativeScrollBarTest, ScrollBarFitsToBottom); 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int GetThumbSizeForTest(); 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Changes to 'pushed' state and starts a timer to scroll repeatedly. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessPressEvent(const ui::LocatedEvent& event); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sets state to |state| and stops the repeater. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetState(CustomButton::ButtonState state); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the mouse is pressed down in the track area. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TrackClicked(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Responsible for scrolling the contents and also updating the UI to the 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current value of the Scroll Offset. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScrollContentsToOffset(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the size (width or height) of the track area of the ScrollBar. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetTrackSize() const; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate the position of the thumb within the track based on the 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified scroll offset of the contents. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CalculateThumbPosition(int contents_scroll_offset) const; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculates the current value of the contents offset (contents coordinates) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // based on the current thumb position (thumb track coordinates). See 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ScrollToThumbPosition| for an explanation of |scroll_to_middle|. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CalculateContentsOffset(int thumb_position, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool scroll_to_middle) const; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the state of the thumb track changes (e.g. by the user 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pressing the mouse button down in it). 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetThumbTrackState(CustomButton::ButtonState state); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BaseScrollBarThumb* thumb_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size of the scrolled contents, in pixels. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int contents_size_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The current amount the contents is offset by in the viewport. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int contents_scroll_offset_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The current size of the view port, in pixels. 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int viewport_size_; 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The state of the scrollbar track. Typically, the track will highlight when 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the user presses the mouse on them (during page scrolling). 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CustomButton::ButtonState thumb_track_state_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The last amount of incremental scroll that this scrollbar performed. This 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is accessed by the callbacks for the auto-repeat up/down buttons to know 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // what direction to repeatedly scroll in. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScrollAmount last_scroll_amount_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An instance of a RepeatController which scrolls the scrollbar continuously 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the user presses the mouse button down on the up/down buttons or the 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // track. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepeatController repeater_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The position of the mouse within the scroll bar when the context menu 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was invoked. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int context_menu_mouse_position_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MenuRunner> menu_runner_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ScrollAnimator> scroll_animator_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Difference between current position and cumulative deltas obtained from 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // scroll update events. 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(tdresser): This should be removed when raw pixel scrolling for views 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is enabled. See crbug.com/329354. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Vector2dF roundoff_error_; 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BaseScrollBar); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_ 193