106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen/* 206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * Copyright (C) 2010 Google Inc. All rights reserved. 306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * 406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * Redistribution and use in source and binary forms, with or without 506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * modification, are permitted provided that the following conditions are 606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * met: 706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * 806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * * Redistributions of source code must retain the above copyright 906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * notice, this list of conditions and the following disclaimer. 1006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * * Redistributions in binary form must reproduce the above 1106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * copyright notice, this list of conditions and the following disclaimer 1206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * in the documentation and/or other materials provided with the 1306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * distribution. 1406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * * Neither the name of Google Inc. nor the names of its 1506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * contributors may be used to endorse or promote products derived from 1606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * this software without specific prior written permission. 1706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * 1806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen */ 3006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 3106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "config.h" 3206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "DragScrollTimer.h" 3306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 3406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "FrameView.h" 3506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 3606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenusing namespace WebCore; 3706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 3806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsennamespace WebKit { 3906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 4006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// Computes the distance from a point outside a rect to the nearest edge of the rect. 4106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenstatic IntSize distanceToRect(const IntPoint& point, const IntRect& rect) 4206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 4306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen int dx = 0, dy = 0; 4406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (point.x() < rect.x()) 4506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen dx = point.x() - rect.x(); 462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else if (rect.maxX() < point.x()) 472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block dx = point.x() - rect.maxX(); 4806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (point.y() < rect.y()) 4906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen dy = point.y() - rect.y(); 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else if (rect.maxY() < point.y()) 512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block dy = point.y() - rect.maxY(); 5206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return IntSize(dx, dy); 5306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 5406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 5506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenDragScrollTimer::DragScrollTimer() 5606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen : m_timer(this, &DragScrollTimer::fired) 5706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_view(0) 5806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_scrolling(false) 5906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 6006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 6206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenDragScrollTimer::~DragScrollTimer() 6306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 6406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // We do this for detecting dead object earlier 6506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen stop(); 6606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 6706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 6806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenvoid DragScrollTimer::stop() 6906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 7006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_timer.stop(); 7106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_view = 0; 7206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_scrolling = false; 7306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 7406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 7506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenvoid DragScrollTimer::scroll() 7606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 7706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_view->scrollBy(m_lastDistance); 7806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_scrolling = true; 7906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 8006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 8106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenvoid DragScrollTimer::update() 8206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 8306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (shouldScroll()) 8406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen scroll(); 8506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen else 8606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen stop(); 8706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 8806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 8906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenvoid DragScrollTimer::triggerScroll(FrameView* view, const WebPoint& location) 9006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 9106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!view) 9206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return; 9306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 9406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Approximates Safari 9506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen static const double scrollStartDelay = 0.2; 9606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 9706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_view = view; 9806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_lastDistance = scrollDistanceFor(view, location); 9906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 10006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (m_scrolling) 10106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen update(); 10206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen else if (shouldScroll() && !m_timer.isActive()) 10306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_timer.startOneShot(scrollStartDelay); 10406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 10506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 10606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenIntSize DragScrollTimer::scrollDistanceFor(FrameView* view, const WebPoint& location) const 10706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 10806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen static const int scrollMargin = 30; 10906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 11006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen IntRect bounds(0, 0, view->visibleWidth(), view->visibleHeight()); 11106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!bounds.contains(location)) 11206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return IntSize(0, 0); // The location is outside the border belt. 11306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 11406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bounds.setY(bounds.y() + scrollMargin); 11506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bounds.setHeight(bounds.height() - scrollMargin * 2); 11606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bounds.setX(bounds.x() + scrollMargin); 11706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen bounds.setWidth(bounds.width() - scrollMargin * 2); 11806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 11906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (bounds.contains(location)) 12006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return IntSize(0, 0); // The location is inside the border belt. 12106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 12206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // The location is over the border belt. 12306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen return distanceToRect(location, bounds); 12406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 12506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 12606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} // namespace WebKit 127