Home | History | Annotate | Download | only in platform
      1 /*
      2  * Copyright (c) 2010, Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "ScrollAnimator.h"
     33 
     34 #include "FloatPoint.h"
     35 #include "PlatformWheelEvent.h"
     36 #include "ScrollableArea.h"
     37 #include <algorithm>
     38 #include <wtf/PassOwnPtr.h>
     39 
     40 using namespace std;
     41 
     42 namespace WebCore {
     43 
     44 #if !ENABLE(SMOOTH_SCROLLING)
     45 PassOwnPtr<ScrollAnimator> ScrollAnimator::create(ScrollableArea* scrollableArea)
     46 {
     47     return adoptPtr(new ScrollAnimator(scrollableArea));
     48 }
     49 #endif
     50 
     51 ScrollAnimator::ScrollAnimator(ScrollableArea* scrollableArea)
     52     : m_scrollableArea(scrollableArea)
     53     , m_currentPosX(0)
     54     , m_currentPosY(0)
     55 {
     56 }
     57 
     58 ScrollAnimator::~ScrollAnimator()
     59 {
     60 }
     61 
     62 bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier)
     63 {
     64     float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY;
     65     float newPos = std::max(std::min(*currentPos + (step * multiplier), static_cast<float>(m_scrollableArea->scrollSize(orientation))), 0.0f);
     66     if (*currentPos == newPos)
     67         return false;
     68     *currentPos = newPos;
     69 
     70     notityPositionChanged();
     71 
     72     return true;
     73 }
     74 
     75 void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
     76 {
     77     if (m_currentPosX != offset.x() || m_currentPosY != offset.y()) {
     78         m_currentPosX = offset.x();
     79         m_currentPosY = offset.y();
     80         notityPositionChanged();
     81     }
     82 }
     83 
     84 void ScrollAnimator::handleWheelEvent(PlatformWheelEvent& e)
     85 {
     86     Scrollbar* horizontalScrollbar = m_scrollableArea->horizontalScrollbar();
     87     Scrollbar* verticalScrollbar = m_scrollableArea->verticalScrollbar();
     88 
     89     // Accept the event if we have a scrollbar in that direction and can still
     90     // scroll any further.
     91     float deltaX = horizontalScrollbar ? e.deltaX() : 0;
     92     float deltaY = verticalScrollbar ? e.deltaY() : 0;
     93 
     94     IntSize maxForwardScrollDelta = m_scrollableArea->maximumScrollPosition() - m_scrollableArea->scrollPosition();
     95     IntSize maxBackwardScrollDelta = m_scrollableArea->scrollPosition() - m_scrollableArea->minimumScrollPosition();
     96     if ((deltaX < 0 && maxForwardScrollDelta.width() > 0)
     97         || (deltaX > 0 && maxBackwardScrollDelta.width() > 0)
     98         || (deltaY < 0 && maxForwardScrollDelta.height() > 0)
     99         || (deltaY > 0 && maxBackwardScrollDelta.height() > 0)) {
    100         e.accept();
    101         if (e.granularity() == ScrollByPageWheelEvent) {
    102             ASSERT(!e.deltaX());
    103             bool negative = deltaY < 0;
    104             deltaY = max(max(static_cast<float>(m_scrollableArea->visibleHeight()) * Scrollbar::minFractionToStepWhenPaging(), static_cast<float>(m_scrollableArea->visibleHeight() - Scrollbar::maxOverlapBetweenPages())), 1.0f);
    105             if (negative)
    106                 deltaY = -deltaY;
    107         }
    108 
    109         if (deltaY)
    110             scroll(VerticalScrollbar, ScrollByPixel, verticalScrollbar->pixelStep(), -deltaY);
    111         if (deltaX)
    112             scroll(HorizontalScrollbar, ScrollByPixel, horizontalScrollbar->pixelStep(), -deltaX);
    113     }
    114 }
    115 
    116 #if ENABLE(GESTURE_EVENTS)
    117 void ScrollAnimator::handleGestureEvent(const PlatformGestureEvent&)
    118 {
    119 }
    120 #endif
    121 
    122 FloatPoint ScrollAnimator::currentPosition() const
    123 {
    124     return FloatPoint(m_currentPosX, m_currentPosY);
    125 }
    126 
    127 void ScrollAnimator::notityPositionChanged()
    128 {
    129     m_scrollableArea->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
    130 }
    131 
    132 } // namespace WebCore
    133