Home | History | Annotate | Download | only in scrollbar
      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