summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/Scrollbar.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:41 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:41 -0800
commit648161bb0edfc3d43db63caed5cc5213bc6cb78f (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /WebCore/platform/Scrollbar.cpp
parenta65af38181ac7d34544586bdb5cd004de93897ad (diff)
downloadexternal_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.zip
external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.gz
external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebCore/platform/Scrollbar.cpp')
-rw-r--r--WebCore/platform/Scrollbar.cpp451
1 files changed, 0 insertions, 451 deletions
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp
deleted file mode 100644
index 0c7d854..0000000
--- a/WebCore/platform/Scrollbar.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Scrollbar.h"
-
-#include "EventHandler.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "PlatformMouseEvent.h"
-#include "ScrollbarClient.h"
-#include "ScrollbarTheme.h"
-
-#include <algorithm>
-
-using std::max;
-using std::min;
-
-namespace WebCore {
-
-#if !PLATFORM(GTK)
-PassRefPtr<Scrollbar> Scrollbar::createNativeScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size)
-{
- return adoptRef(new Scrollbar(client, orientation, size));
-}
-#endif
-
-Scrollbar::Scrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize,
- ScrollbarTheme* theme)
- : m_client(client)
- , m_orientation(orientation)
- , m_controlSize(controlSize)
- , m_theme(theme)
- , m_visibleSize(0)
- , m_totalSize(0)
- , m_currentPos(0)
- , m_lineStep(0)
- , m_pageStep(0)
- , m_pixelStep(1)
- , m_hoveredPart(NoPart)
- , m_pressedPart(NoPart)
- , m_pressedPos(0)
- , m_enabled(true)
- , m_scrollTimer(this, &Scrollbar::autoscrollTimerFired)
- , m_overlapsResizer(false)
- , m_suppressInvalidation(false)
-{
- if (!m_theme)
- m_theme = ScrollbarTheme::nativeTheme();
-
- m_theme->registerScrollbar(this);
-
- // FIXME: This is ugly and would not be necessary if we fix cross-platform code to actually query for
- // scrollbar thickness and use it when sizing scrollbars (rather than leaving one dimension of the scrollbar
- // alone when sizing).
- int thickness = m_theme->scrollbarThickness(controlSize);
- Widget::setFrameRect(IntRect(0, 0, thickness, thickness));
-}
-
-Scrollbar::~Scrollbar()
-{
- stopTimerIfNeeded();
-
- m_theme->unregisterScrollbar(this);
-}
-
-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);
-
- return true;
-}
-
-void Scrollbar::setProportion(int visibleSize, int totalSize)
-{
- if (visibleSize == m_visibleSize && totalSize == m_totalSize)
- return;
-
- m_visibleSize = visibleSize;
- m_totalSize = totalSize;
-
- updateThumbProportion();
-}
-
-void Scrollbar::setSteps(int lineStep, int pageStep, int pixelsPerStep)
-{
- m_lineStep = lineStep;
- m_pageStep = pageStep;
- m_pixelStep = 1.0f / pixelsPerStep;
-}
-
-bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
-{
- float step = 0;
- if ((direction == ScrollUp && m_orientation == VerticalScrollbar) || (direction == ScrollLeft && m_orientation == HorizontalScrollbar))
- step = -1;
- else if ((direction == ScrollDown && m_orientation == VerticalScrollbar) || (direction == ScrollRight && m_orientation == HorizontalScrollbar))
- step = 1;
-
- if (granularity == ScrollByLine)
- step *= m_lineStep;
- else if (granularity == ScrollByPage)
- step *= m_pageStep;
- else if (granularity == ScrollByDocument)
- step *= m_totalSize;
- else if (granularity == ScrollByPixel)
- step *= m_pixelStep;
-
- 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;
-}
-
-void Scrollbar::updateThumbPosition()
-{
- theme()->invalidateParts(this, ForwardTrackPart | BackTrackPart | ThumbPart);
-}
-
-void Scrollbar::updateThumbProportion()
-{
- theme()->invalidateParts(this, ForwardTrackPart | BackTrackPart | ThumbPart);
-}
-
-void Scrollbar::paint(GraphicsContext* context, const IntRect& damageRect)
-{
- if (context->updatingControlTints() && theme()->supportsControlTints()) {
- invalidate();
- return;
- }
-
- if (context->paintingDisabled() || !frameRect().intersects(damageRect))
- return;
-
- if (!theme()->paint(this, context, damageRect))
- Widget::paint(context, damageRect);
-}
-
-void Scrollbar::autoscrollTimerFired(Timer<Scrollbar>*)
-{
- autoscrollPressedPart(theme()->autoscrollTimerDelay());
-}
-
-static bool thumbUnderMouse(Scrollbar* scrollbar)
-{
- int thumbPos = scrollbar->theme()->trackPosition(scrollbar) + scrollbar->theme()->thumbPosition(scrollbar);
- int thumbLength = scrollbar->theme()->thumbLength(scrollbar);
- return scrollbar->pressedPos() >= thumbPos && scrollbar->pressedPos() < thumbPos + thumbLength;
-}
-
-void Scrollbar::autoscrollPressedPart(double delay)
-{
- // Don't do anything for the thumb or if nothing was pressed.
- if (m_pressedPart == ThumbPart || m_pressedPart == NoPart)
- return;
-
- // Handle the track.
- if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
- theme()->invalidatePart(this, m_pressedPart);
- setHoveredPart(ThumbPart);
- return;
- }
-
- // Handle the arrows and track.
- if (scroll(pressedPartScrollDirection(), pressedPartScrollGranularity()))
- startTimerIfNeeded(delay);
-}
-
-void Scrollbar::startTimerIfNeeded(double delay)
-{
- // Don't do anything for the thumb.
- if (m_pressedPart == ThumbPart)
- return;
-
- // Handle the track. We halt track scrolling once the thumb is level
- // with us.
- if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
- theme()->invalidatePart(this, m_pressedPart);
- setHoveredPart(ThumbPart);
- return;
- }
-
- // We can't scroll if we've hit the beginning or end.
- ScrollDirection dir = pressedPartScrollDirection();
- if (dir == ScrollUp || dir == ScrollLeft) {
- if (m_currentPos == 0)
- return;
- } else {
- if (m_currentPos == maximum())
- return;
- }
-
- m_scrollTimer.startOneShot(delay);
-}
-
-void Scrollbar::stopTimerIfNeeded()
-{
- if (m_scrollTimer.isActive())
- m_scrollTimer.stop();
-}
-
-ScrollDirection Scrollbar::pressedPartScrollDirection()
-{
- if (m_orientation == HorizontalScrollbar) {
- if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart || m_pressedPart == BackTrackPart)
- return ScrollLeft;
- return ScrollRight;
- } else {
- if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart || m_pressedPart == BackTrackPart)
- return ScrollUp;
- return ScrollDown;
- }
-}
-
-ScrollGranularity Scrollbar::pressedPartScrollGranularity()
-{
- if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart || m_pressedPart == ForwardButtonStartPart || m_pressedPart == ForwardButtonEndPart)
- return ScrollByLine;
- return ScrollByPage;
-}
-
-void Scrollbar::moveThumb(int pos)
-{
- // Drag the thumb.
- int thumbPos = theme()->thumbPosition(this);
- int thumbLen = theme()->thumbLength(this);
- int trackLen = theme()->trackLength(this);
- int maxPos = trackLen - thumbLen;
- int delta = pos - 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);
- }
-}
-
-void Scrollbar::setHoveredPart(ScrollbarPart part)
-{
- if (part == m_hoveredPart)
- return;
-
- 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) {
- theme()->invalidatePart(this, part);
- theme()->invalidatePart(this, m_hoveredPart);
- }
- m_hoveredPart = part;
-}
-
-void Scrollbar::setPressedPart(ScrollbarPart part)
-{
- if (m_pressedPart != NoPart)
- theme()->invalidatePart(this, m_pressedPart);
- m_pressedPart = part;
- if (m_pressedPart != NoPart)
- theme()->invalidatePart(this, m_pressedPart);
-}
-
-bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
-{
- if (m_pressedPart == ThumbPart) {
- moveThumb(m_orientation == HorizontalScrollbar ?
- convertFromContainingWindow(evt.pos()).x() :
- convertFromContainingWindow(evt.pos()).y());
- return true;
- }
-
- if (m_pressedPart != NoPart)
- m_pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());
-
- ScrollbarPart part = theme()->hitTest(this, evt);
- if (part != m_hoveredPart) {
- if (m_pressedPart != NoPart) {
- if (part == m_pressedPart) {
- // The mouse is moving back over the pressed part. We
- // need to start up the timer action again.
- startTimerIfNeeded(theme()->autoscrollTimerDelay());
- theme()->invalidatePart(this, m_pressedPart);
- } else if (m_hoveredPart == m_pressedPart) {
- // The mouse is leaving the pressed part. Kill our timer
- // if needed.
- stopTimerIfNeeded();
- theme()->invalidatePart(this, m_pressedPart);
- }
- }
-
- setHoveredPart(part);
- }
-
- return true;
-}
-
-bool Scrollbar::mouseExited()
-{
- setHoveredPart(NoPart);
- return true;
-}
-
-bool Scrollbar::mouseUp()
-{
- setPressedPart(NoPart);
- m_pressedPos = 0;
- stopTimerIfNeeded();
-
- if (parent() && parent()->isFrameView())
- static_cast<FrameView*>(parent())->frame()->eventHandler()->setMousePressed(false);
-
- return true;
-}
-
-bool Scrollbar::mouseDown(const PlatformMouseEvent& evt)
-{
- // Early exit for right click
- if (evt.button() == RightButton)
- return true; // FIXME: Handled as context menu by Qt right now. Should just avoid even calling this method on a right click though.
-
- setPressedPart(theme()->hitTest(this, evt));
- int pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());
-
- if (theme()->shouldCenterOnThumb(this, evt)) {
- setHoveredPart(ThumbPart);
- setPressedPart(ThumbPart);
- int thumbLen = theme()->thumbLength(this);
- int desiredPos = pressedPos - thumbLen / 2;
- // Set the pressed position to the top of the thumb so that when we do the move, the delta
- // will be from the current pixel position of the thumb to the new desired position for the thumb.
- m_pressedPos = theme()->trackPosition(this) + theme()->thumbPosition(this);
- moveThumb(desiredPos);
- return true;
- }
-
- m_pressedPos = pressedPos;
-
- autoscrollPressedPart(theme()->initialAutoscrollTimerDelay());
- return true;
-}
-
-void Scrollbar::setFrameRect(const IntRect& rect)
-{
- // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap
- // if necessary.
- IntRect adjustedRect(rect);
- if (parent()) {
- bool overlapsResizer = false;
- ScrollView* view = parent();
- IntRect resizerRect = view->convertFromContainingWindow(view->windowResizerRect());
- if (rect.intersects(resizerRect)) {
- if (orientation() == HorizontalScrollbar) {
- int overlap = rect.right() - resizerRect.x();
- if (overlap > 0 && resizerRect.right() >= rect.right()) {
- adjustedRect.setWidth(rect.width() - overlap);
- overlapsResizer = true;
- }
- } else {
- int overlap = rect.bottom() - resizerRect.y();
- if (overlap > 0 && resizerRect.bottom() >= rect.bottom()) {
- adjustedRect.setHeight(rect.height() - overlap);
- overlapsResizer = true;
- }
- }
- }
-
- if (overlapsResizer != m_overlapsResizer) {
- m_overlapsResizer = overlapsResizer;
- view->adjustScrollbarsAvoidingResizerCount(m_overlapsResizer ? 1 : -1);
- }
- }
-
- Widget::setFrameRect(adjustedRect);
-}
-
-void Scrollbar::setParent(ScrollView* parentView)
-{
- if (!parentView && m_overlapsResizer && parent())
- parent()->adjustScrollbarsAvoidingResizerCount(-1);
- Widget::setParent(parentView);
-}
-
-void Scrollbar::setEnabled(bool e)
-{
- if (m_enabled == e)
- return;
- m_enabled = e;
- invalidate();
-}
-
-bool Scrollbar::isWindowActive() const
-{
- return m_client->isActive();
-}
-
-void Scrollbar::invalidateRect(const IntRect& rect)
-{
- if (suppressInvalidation())
- return;
- m_client->invalidateScrollbarRect(this, rect);
-}
-
-PlatformMouseEvent Scrollbar::transformEvent(const PlatformMouseEvent& event)
-{
- return event;
-}
-
-}