diff options
Diffstat (limited to 'WebCore/platform/Scrollbar.cpp')
-rw-r--r-- | WebCore/platform/Scrollbar.cpp | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp index 13bb0c9..babf3d4 100644 --- a/WebCore/platform/Scrollbar.cpp +++ b/WebCore/platform/Scrollbar.cpp @@ -57,6 +57,7 @@ Scrollbar::Scrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, , m_visibleSize(0) , m_totalSize(0) , m_currentPos(0) + , m_dragOrigin(0) , m_lineStep(0) , m_pageStep(0) , m_pixelStep(1) @@ -92,13 +93,7 @@ bool Scrollbar::setValue(int v) v = max(min(v, m_totalSize - m_visibleSize), 0); if (value() == v) return false; // Our value stayed the same. - m_currentPos = v; - - updateThumbPosition(); - - if (client()) - client()->valueChanged(this); - + setCurrentPos(v); return true; } @@ -139,20 +134,7 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, float newPos = m_currentPos + step * multiplier; float maxPos = m_totalSize - m_visibleSize; - newPos = max(min(newPos, maxPos), 0.0f); - - if (newPos == m_currentPos) - return false; - - int oldValue = value(); - m_currentPos = newPos; - updateThumbPosition(); - - if (value() != oldValue && client()) - client()->valueChanged(this); - - // return true even if the integer value did not change so that scroll event gets eaten - return true; + return setCurrentPos(max(min(newPos, maxPos), 0.0f)); } void Scrollbar::updateThumbPosition() @@ -269,15 +251,30 @@ void Scrollbar::moveThumb(int pos) int thumbLen = theme()->thumbLength(this); int trackLen = theme()->trackLength(this); int maxPos = trackLen - thumbLen; - int delta = pos - pressedPos(); + int delta = pos - m_pressedPos; if (delta > 0) delta = min(maxPos - thumbPos, delta); else if (delta < 0) delta = max(-thumbPos, delta); - if (delta) { - setValue(static_cast<int>(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen))); - setPressedPos(pressedPos() + theme()->thumbPosition(this) - thumbPos); - } + if (delta) + setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen)); +} + +bool Scrollbar::setCurrentPos(float pos) +{ + if (pos == m_currentPos) + return false; + + int oldValue = value(); + int oldThumbPos = theme()->thumbPosition(this); + m_currentPos = pos; + updateThumbPosition(); + if (m_pressedPart == ThumbPart) + setPressedPos(m_pressedPos + theme()->thumbPosition(this) - oldThumbPos); + + if (value() != oldValue && client()) + client()->valueChanged(this); + return true; } void Scrollbar::setHoveredPart(ScrollbarPart part) @@ -287,7 +284,7 @@ void Scrollbar::setHoveredPart(ScrollbarPart part) if ((m_hoveredPart == NoPart || part == NoPart) && theme()->invalidateOnMouseEnterExit()) invalidate(); // Just invalidate the whole scrollbar, since the buttons at either end change anyway. - else if (m_pressedPart == NoPart) { + else if (m_pressedPart == NoPart) { // When there's a pressed part, we don't draw a hovered state, so there's no reason to invalidate. theme()->invalidatePart(this, part); theme()->invalidatePart(this, m_hoveredPart); } @@ -301,14 +298,20 @@ void Scrollbar::setPressedPart(ScrollbarPart part) m_pressedPart = part; if (m_pressedPart != NoPart) theme()->invalidatePart(this, m_pressedPart); + else if (m_hoveredPart != NoPart) // When we no longer have a pressed part, we can start drawing a hovered state on the hovered part. + theme()->invalidatePart(this, m_hoveredPart); } bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt) { if (m_pressedPart == ThumbPart) { - moveThumb(m_orientation == HorizontalScrollbar ? - convertFromContainingWindow(evt.pos()).x() : - convertFromContainingWindow(evt.pos()).y()); + if (theme()->shouldSnapBackToDragOrigin(this, evt)) + setCurrentPos(m_dragOrigin); + else { + moveThumb(m_orientation == HorizontalScrollbar ? + convertFromContainingWindow(evt.pos()).x() : + convertFromContainingWindow(evt.pos()).y()); + } return true; } @@ -364,9 +367,10 @@ bool Scrollbar::mouseDown(const PlatformMouseEvent& evt) setPressedPart(theme()->hitTest(this, evt)); int pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y()); - if ((pressedPart() == BackTrackPart || pressedPart() == ForwardTrackPart) && theme()->shouldCenterOnThumb(this, evt)) { + if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && theme()->shouldCenterOnThumb(this, evt)) { setHoveredPart(ThumbPart); setPressedPart(ThumbPart); + m_dragOrigin = m_currentPos; int thumbLen = theme()->thumbLength(this); int desiredPos = pressedPos; // Set the pressed position to the middle of the thumb so that when we do the move, the delta @@ -374,7 +378,8 @@ bool Scrollbar::mouseDown(const PlatformMouseEvent& evt) m_pressedPos = theme()->trackPosition(this) + theme()->thumbPosition(this) + thumbLen / 2; moveThumb(desiredPos); return true; - } + } else if (m_pressedPart == ThumbPart) + m_dragOrigin = m_currentPos; m_pressedPos = pressedPos; |