webengine/osswebengine/WebKit/s60/webview/WebScrollingDecelerator.cpp
changeset 0 dd21522fd290
child 47 e1bea15f9a39
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/s60/webview/WebScrollingDecelerator.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,186 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Implementation of scrolling decelerator
+*
+*/
+
+
+// INCLUDE FILES
+#include <../bidi.h>
+#include "WebScrollingDecelerator.h"
+#include "WebView.h"
+#include "WebFrame.h"
+#include "WebFrameView.h"
+#include "WebPageScrollHandler.h"
+#include "PlatformScrollbar.h"
+
+// constants
+const int KRecordSize = 4;
+
+// The following deceleration curve is generated by a script
+// It lists the timeout dt values in microseconds.
+const int KDecelCurveSize = 10;
+
+const int KScrollIntervalTimeout = 40000; // scroll timer interval in microseconds
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::NewL
+// The two-phase Symbian constructor
+// -----------------------------------------------------------------------------
+//
+
+WebScrollingDecelerator* WebScrollingDecelerator::NewL(WebView& webView)
+{
+    WebScrollingDecelerator* self = new (ELeave) WebScrollingDecelerator(webView);
+
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(); //self
+    return self;
+}
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::WebScrollingDecelerator
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+WebScrollingDecelerator::WebScrollingDecelerator(WebView& webView)
+: CTimer(EPriorityHigh), m_webView( webView )
+{
+}
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::ConstructL
+// -----------------------------------------------------------------------------
+void WebScrollingDecelerator::ConstructL()
+{
+    CTimer::ConstructL();
+    CActiveScheduler::Add( this );
+    m_dragPosition.Reset();
+}
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+WebScrollingDecelerator::~WebScrollingDecelerator()
+{
+    Cancel();
+}
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::updatePos
+// update record of position
+// -----------------------------------------------------------------------------
+//
+void WebScrollingDecelerator::updatePos()
+{
+    if (m_dragPosition.Count() >= KRecordSize)
+      {
+        // pop item from front   
+        m_dragPosition.Remove(0);
+      }
+    
+    // and add this one to the end
+    TPoint currPosition = m_webView.pageScrollHandler()->currentScrollingFrameView()->contentPos();
+    m_dragPosition.Append(currPosition);
+}
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::startDecel
+// initialize and start deceleration
+// -----------------------------------------------------------------------------
+//
+void WebScrollingDecelerator::startDecelL()
+{
+    int count = m_dragPosition.Count();
+        
+    m_normalizedCurrentPosition.iX = m_webView.pageScrollHandler()->currentScrollingFrameView()->contentPos().iX * 100;
+    m_normalizedCurrentPosition.iY = m_webView.pageScrollHandler()->currentScrollingFrameView()->contentPos().iY * 100;
+    
+    if (count > 0)
+      {     
+
+      // set the delta based upon the change span of points collected averaged over the span, so long as we have moved
+        int dx = (m_dragPosition[count - 1].iX - m_dragPosition[0].iX)* 100;
+        int dy = (m_dragPosition[count - 1].iY - m_dragPosition[0].iY) * 100;
+ 
+        if (abs(dx) > 0 || abs(dy) > 0)
+            {           
+            m_scrolldelta.SetXY( (dx/count), (dy/count) );
+            WebFrameView* view = m_webView.pageScrollHandler()->currentScrollingFrameView();
+            
+            m_scrolldelta = view->toDocCoords(m_scrolldelta);
+            
+            // init num steps
+            m_numscrollsteps = 0;
+
+            // call the RunL function directly, this first time. CTimer will call it from now on.
+            m_decelelatorSwitch = ETrue;
+            
+            RunL();
+            }
+        }
+        m_dragPosition.Reset();
+}
+
+// -----------------------------------------------------------------------------
+// WebScrollingDecelerator::RunL
+// continue deceleration
+// -----------------------------------------------------------------------------
+//
+void WebScrollingDecelerator::RunL()
+{
+  WebFrameView* scrollingView = m_webView.pageScrollHandler()->currentScrollingFrameView();
+    // use a pre-calulated deceleration curve to calculate dt
+    if ((m_numscrollsteps >= KDecelCurveSize ) || !m_decelelatorSwitch)
+      {
+        // done
+        Cancel();
+        m_webView.setViewIsScrolling(false);
+        return;
+      }
+    
+    // step to next
+    m_numscrollsteps++;
+
+    // do the scrolling
+    
+    if (m_webView.pageScrollHandler() && scrollingView) {
+        
+        TPoint newpos;
+        
+        /* With each step decrease m_scrolldelta by 50% */
+        m_scrolldelta.iX = m_scrolldelta.iX >> 1;
+        m_scrolldelta.iY = m_scrolldelta.iY >> 1;
+                
+        m_normalizedCurrentPosition += m_scrolldelta;
+        newpos.iX = m_normalizedCurrentPosition.iX/100;
+        newpos.iY = m_normalizedCurrentPosition.iY/100;
+        scrollingView->scrollTo(newpos);
+
+        if (scrollingView->vScrollbar()) {
+            scrollingView->vScrollbar()->setValue(newpos.iY);
+        }
+        if (scrollingView->hScrollbar()) {
+            scrollingView->hScrollbar()->setValue(newpos.iX);
+        }
+
+        After(KScrollIntervalTimeout);
+    }
+}
+
+//  End of File