1 // Copyright (c) 2011 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.
5 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
7 #include "ui/gfx/canvas.h"
8 #include "ui/gfx/geometry/rect.h"
9 #include "ui/views/controls/scrollbar/base_scroll_bar.h"
12 // The distance the mouse can be dragged outside the bounds of the thumb during
13 // dragging before the scrollbar will snap back to its regular position.
14 static const int kScrollThumbDragOutSnap
= 100;
19 BaseScrollBarThumb::BaseScrollBarThumb(BaseScrollBar
* scroll_bar
)
20 : scroll_bar_(scroll_bar
),
21 drag_start_position_(-1),
23 state_(CustomButton::STATE_NORMAL
) {
26 BaseScrollBarThumb::~BaseScrollBarThumb() {
29 void BaseScrollBarThumb::SetSize(int size
) {
30 // Make sure the thumb is never sized smaller than its minimum possible
32 gfx::Size prefsize
= GetPreferredSize();
33 size
= std::max(size
, scroll_bar_
->IsHorizontal() ? prefsize
.width() :
35 gfx::Rect thumb_bounds
= bounds();
36 if (scroll_bar_
->IsHorizontal()) {
37 thumb_bounds
.set_width(size
);
39 thumb_bounds
.set_height(size
);
41 SetBoundsRect(thumb_bounds
);
44 int BaseScrollBarThumb::GetSize() const {
45 if (scroll_bar_
->IsHorizontal())
50 void BaseScrollBarThumb::SetPosition(int position
) {
51 gfx::Rect thumb_bounds
= bounds();
52 gfx::Rect track_bounds
= scroll_bar_
->GetTrackBounds();
53 if (scroll_bar_
->IsHorizontal()) {
54 thumb_bounds
.set_x(track_bounds
.x() + position
);
56 thumb_bounds
.set_y(track_bounds
.y() + position
);
58 SetBoundsRect(thumb_bounds
);
61 int BaseScrollBarThumb::GetPosition() const {
62 gfx::Rect track_bounds
= scroll_bar_
->GetTrackBounds();
63 if (scroll_bar_
->IsHorizontal())
64 return x() - track_bounds
.x();
65 return y() - track_bounds
.y();
68 void BaseScrollBarThumb::OnMouseEntered(const ui::MouseEvent
& event
) {
69 SetState(CustomButton::STATE_HOVERED
);
72 void BaseScrollBarThumb::OnMouseExited(const ui::MouseEvent
& event
) {
73 SetState(CustomButton::STATE_NORMAL
);
76 bool BaseScrollBarThumb::OnMousePressed(const ui::MouseEvent
& event
) {
77 mouse_offset_
= scroll_bar_
->IsHorizontal() ? event
.x() : event
.y();
78 drag_start_position_
= GetPosition();
79 SetState(CustomButton::STATE_PRESSED
);
83 bool BaseScrollBarThumb::OnMouseDragged(const ui::MouseEvent
& event
) {
84 // If the user moves the mouse more than |kScrollThumbDragOutSnap| outside
85 // the bounds of the thumb, the scrollbar will snap the scroll back to the
86 // point it was at before the drag began.
87 if (scroll_bar_
->IsHorizontal()) {
88 if ((event
.y() < y() - kScrollThumbDragOutSnap
) ||
89 (event
.y() > (y() + height() + kScrollThumbDragOutSnap
))) {
90 scroll_bar_
->ScrollToThumbPosition(drag_start_position_
, false);
94 if ((event
.x() < x() - kScrollThumbDragOutSnap
) ||
95 (event
.x() > (x() + width() + kScrollThumbDragOutSnap
))) {
96 scroll_bar_
->ScrollToThumbPosition(drag_start_position_
, false);
100 if (scroll_bar_
->IsHorizontal()) {
101 int thumb_x
= event
.x() - mouse_offset_
;
102 if (base::i18n::IsRTL())
104 scroll_bar_
->ScrollToThumbPosition(GetPosition() + thumb_x
, false);
106 int thumb_y
= event
.y() - mouse_offset_
;
107 scroll_bar_
->ScrollToThumbPosition(GetPosition() + thumb_y
, false);
112 void BaseScrollBarThumb::OnMouseReleased(const ui::MouseEvent
& event
) {
113 SetState(HitTestPoint(event
.location()) ?
114 CustomButton::STATE_HOVERED
: CustomButton::STATE_NORMAL
);
117 void BaseScrollBarThumb::OnMouseCaptureLost() {
118 SetState(CustomButton::STATE_HOVERED
);
121 CustomButton::ButtonState
BaseScrollBarThumb::GetState() const {
125 void BaseScrollBarThumb::SetState(CustomButton::ButtonState state
) {
129 CustomButton::ButtonState old_state
= state_
;
131 scroll_bar_
->OnThumbStateChanged(old_state
, state
);