webengine/osswebengine/WebKit/s60/webview/WebPageScrollHandler.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of drag scrolling
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <Browser_platform_variant.hrh>
       
    21 #include <../bidi.h>
       
    22 #include "WebPageScrollHandler.h"
       
    23 #include "BrCtl.h"
       
    24 #include "WebFrame.h"
       
    25 #include "WebFrameView.h"
       
    26 #include "WebView.h"
       
    27 #include <AknUtils.h>
       
    28 #include "Page.h"
       
    29 #include "Frame.h"
       
    30 #include "WebCoreFrameBridge.h"
       
    31 #include "FrameView.h"
       
    32 #include "FocusController.h"
       
    33 #include "PlatformScrollbar.h"
       
    34 #include "WebScrollbarDrawer.h"
       
    35 #include "RenderObject.h"
       
    36 #include "WebScrollingDeceleratorGH.h"
       
    37 
       
    38 #include "WebKitLogger.h"
       
    39 using namespace WebCore;
       
    40 using namespace RT_GestureHelper;
       
    41 // constants
       
    42 const int KPageOverviewScrollPeriodic = 20 * 1000; // Update frequently for faster, smoother scrolling
       
    43 const int KMicroInterval = 300000;
       
    44 const int KPageOverviewScrollStart = 1000;
       
    45 const int KCancelDecelerationTimeout = 200000; //Decelerate only if flicked KCancelDecelerationTimeout microsec after last drag event.
       
    46 
       
    47 const int KScrollIntervalTimeout = 40000; // scroll timer interval in microseconds
       
    48 const int KAngularDeviationThreshold = 160; // % deviation ignored from minor axis of motion(120 means 20 %)
       
    49 const int KScrollThresholdPixels = 10; // scrolls only if delta is above this threshold
       
    50 const int KScrollDirectionBoundary = 30; // Bound around focal point within which scrolling locks in X or Y states
       
    51 const float KTanOfThresholdAngle = 0.46; // tan of 25 degree
       
    52 
       
    53 int handleScrollTimerEventCallback( TAny* ptr);
       
    54 
       
    55 // ============================= LOCAL FUNCTIONS ===============================
       
    56 int WebPageScrollHandler::pageOverviewScrollCallback( TAny* aPtr )
       
    57 {
       
    58 #ifdef BRDO_USE_GESTURE_HELPER
       
    59     static_cast<WebPageScrollHandler*>(aPtr)->scrollPageOverviewGH();
       
    60 #else
       
    61     static_cast<WebPageScrollHandler*>(aPtr)->handlePageOverviewScrollCallback();
       
    62 #endif //BRDO_USE_GESTURE_HELPER
       
    63     return KErrNone;
       
    64 }
       
    65     
       
    66 int handleScrollTimerEventCallback( TAny* ptr)
       
    67 {
       
    68     WebPageScrollHandler* scrollHandler = static_cast<WebPageScrollHandler*>(ptr);
       
    69     scrollHandler->scrollContent();
       
    70     return EFalse;    
       
    71 }      
       
    72 
       
    73 // ============================ MEMBER FUNCTIONS ===============================
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // ScrollableView::contentPos
       
    77 // 
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 TPoint ScrollableView::contentPos()
       
    81 {
       
    82     WebFrameView* fv = activeFrameView();
       
    83     if (fv) return fv->contentPos();
       
    84     return TPoint (0,0);
       
    85 }
       
    86 
       
    87 WebFrameView* ScrollableView::activeFrameView()
       
    88 {
       
    89     if (m_scrollingElement) {
       
    90         return kit(m_scrollingElement->document()->frame())->frameView();
       
    91     }
       
    92     else {
       
    93         return m_frameView;
       
    94     }
       
    95 }
       
    96 
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // WebPageScrollHandler::NewL
       
   100 // The two-phase Symbian constructor
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 WebPageScrollHandler* WebPageScrollHandler::NewL(WebView& webView)
       
   104     {
       
   105     WebPageScrollHandler* self = new (ELeave) WebPageScrollHandler( webView );
       
   106     CleanupStack::PushL(self);
       
   107     self->constructL();
       
   108     CleanupStack::Pop(); //self
       
   109     return self;
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // WebPageScrollHandler::WebPageScrollHandler
       
   114 // C++ default constructor can NOT contain any code, that
       
   115 // might leave.
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 WebPageScrollHandler::WebPageScrollHandler(WebView& webView)
       
   119 : m_webView( &webView ), m_decel(0), m_decelGH(NULL)
       
   120     {
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // WebPageScrollHandler::constructL
       
   125 // The constructor that can contain code that might leave.
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 void WebPageScrollHandler::constructL()
       
   129     {
       
   130         m_scrollTimer = CPeriodic::NewL(CActive::EPriorityUserInput - 1);
       
   131         m_pageOverviewScrollPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput - 1);
       
   132         m_lastPosition = TPoint(0, 0);
       
   133         
       
   134         if(AknLayoutUtils::PenEnabled()) {
       
   135             m_touchScrolling = true;
       
   136             m_scrollDirectionState = ScrollDirectionUnassigned;
       
   137             m_scrollbarDrawer = WebScrollbarDrawer::NewL();
       
   138 #ifndef BRDO_USE_GESTURE_HELPER            
       
   139             m_decel = WebScrollingDecelerator::NewL(*m_webView);
       
   140 #else            
       
   141 	        m_decelGH = WebScrollingDeceleratorGH::NewL(*m_webView);
       
   142 #endif	    
       
   143         }
       
   144         else  {
       
   145             m_touchScrolling = false;            
       
   146         }
       
   147     }
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // Destructor
       
   151 // -----------------------------------------------------------------------------
       
   152 WebPageScrollHandler::~WebPageScrollHandler()
       
   153 {    
       
   154     
       
   155     if (m_scrollTimer) {
       
   156         m_scrollTimer->Cancel();
       
   157         delete m_scrollTimer;    
       
   158     }
       
   159 
       
   160     if (m_pageOverviewScrollPeriodic) {
       
   161         m_pageOverviewScrollPeriodic->Cancel();
       
   162         delete m_pageOverviewScrollPeriodic;
       
   163     }
       
   164 
       
   165     delete m_decel;
       
   166     delete m_decelGH;
       
   167     delete m_scrollbarDrawer;
       
   168 }
       
   169     
       
   170 void WebPageScrollHandler::handlePageOverviewScrollingL(const TPointerEvent& pointerEvent)
       
   171 {
       
   172     switch (pointerEvent.iType){
       
   173         case TPointerEvent::EButton1Down:            
       
   174             m_webView->setViewIsScrolling(false);
       
   175             m_lastPointerEvent.iPosition.SetXY(0,0);
       
   176             m_lastDragEvent = pointerEvent;
       
   177             break;
       
   178 
       
   179         case TPointerEvent::EDrag:
       
   180             if (!m_webView->viewIsScrolling()){
       
   181                 m_webView->setViewIsScrolling(true);
       
   182                 m_pageOverviewScrollPeriodic->Start( 0, KPageOverviewScrollPeriodic, TCallBack(&pageOverviewScrollCallback, this));
       
   183             }
       
   184             break;
       
   185 
       
   186         case TPointerEvent::EButton1Up:
       
   187             if (m_pageOverviewScrollPeriodic->IsActive()){ 
       
   188                 m_pageOverviewScrollPeriodic->Cancel();
       
   189             }
       
   190             m_webView->closePageView();
       
   191             m_webView->setViewIsScrolling(false);
       
   192             break;
       
   193 
       
   194         default:
       
   195             break;
       
   196    }
       
   197   
       
   198    // Scroll here only for EButton1Up and EButton1Down if needed
       
   199    if(pointerEvent.iType != TPointerEvent::EDrag && m_lastPointerEvent.iPosition != pointerEvent.iPosition){
       
   200        scrollPageOverview( pointerEvent );
       
   201    }
       
   202    m_lastPointerEvent = pointerEvent; 
       
   203 }
       
   204 
       
   205 void WebPageScrollHandler::handlePageOverviewScrollCallback()
       
   206 {
       
   207     int absX = Abs( m_lastDragEvent.iPosition.iX - m_lastPointerEvent.iPosition.iX);
       
   208     int absY = Abs( m_lastDragEvent.iPosition.iY - m_lastPointerEvent.iPosition.iY);
       
   209 
       
   210    // Scrolling for EDrag events
       
   211 
       
   212     if( absX > 3 ||  absY > 3){
       
   213         scrollPageOverview( m_lastPointerEvent );
       
   214         m_lastDragEvent = m_lastPointerEvent;
       
   215     }
       
   216 }
       
   217 
       
   218 
       
   219 void WebPageScrollHandler::scrollPageOverview(const TPointerEvent& pointerEvent)
       
   220 {
       
   221 
       
   222     TRect indicatorRect = m_webView->pageScaler()->IndicatorRect();
       
   223     TInt zoomLevel = m_webView->pageScaler()->ZoomOutLevel();
       
   224     TPoint currentPosition = m_webView->mainFrame()->frameView()->contentPos();
       
   225     TInt xInDoc = ((pointerEvent.iPosition.iX - indicatorRect.iTl.iX  - indicatorRect.Width() / 2) * zoomLevel ) / 100 + currentPosition.iX;
       
   226     TInt yInDoc = ((pointerEvent.iPosition.iY - indicatorRect.iTl.iY  - indicatorRect.Height() / 2) * zoomLevel ) / 100 + currentPosition.iY;
       
   227            
       
   228     m_webView->mainFrame()->frameView()->scrollTo(TPoint(xInDoc, yInDoc));    
       
   229 
       
   230 }
       
   231 
       
   232 void WebPageScrollHandler::updateScrolling(const TPointerEvent& pointerEvent)
       
   233 {
       
   234     switch (pointerEvent.iType)
       
   235     {
       
   236         case TPointerEvent::EButton1Down:
       
   237         {        
       
   238             m_lastMoveEventTime = 0; 
       
   239             m_lastPosition = pointerEvent.iPosition;
       
   240             m_currentPosition = pointerEvent.iPosition;
       
   241             m_webView->setViewIsScrolling(false);         
       
   242             // stop deceleration scrolling cycle            
       
   243             if (m_decel) {
       
   244                 m_decel->stopDecelL();    
       
   245             }
       
   246             m_scrollableView.m_scrollingElement = NULL;
       
   247             m_scrollableView.m_frameView = NULL;
       
   248             break;
       
   249         }
       
   250         case TPointerEvent::EButton1Up:
       
   251         {
       
   252             m_scrollTimer->Cancel();
       
   253             if (m_scrollableView.m_scrollingElement) {
       
   254                 if (m_scrollableView.m_scrollingElement) {
       
   255                     m_scrollableView.m_scrollingElement->deref();
       
   256                     m_scrollableView.m_scrollingElement = NULL;
       
   257                 }
       
   258             }
       
   259             else {
       
   260                 if (m_lastMoveEventTime != 0)
       
   261                 {           
       
   262                     // Start deceleration only if the delta since last drag event is less than threshold
       
   263                     TTime now;
       
   264                     now.HomeTime();             
       
   265                     TTimeIntervalMicroSeconds ms = now.MicroSecondsFrom(m_lastMoveEventTime);
       
   266                     if (ms < KCancelDecelerationTimeout) {
       
   267                         m_decel->startDecelL();    
       
   268                     }
       
   269                 }            
       
   270                 if (m_webView->viewIsScrolling()) {
       
   271                     Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
       
   272                     frame->bridge()->sendScrollEvent();                            
       
   273                 }
       
   274             }
       
   275             m_scrollbarDrawer->fadeScrollbar();
       
   276             m_scrollDirectionState = ScrollDirectionUnassigned;
       
   277             m_lastMoveEventTime = 0;
       
   278             break;
       
   279         }
       
   280     }
       
   281 }
       
   282 
       
   283 void WebPageScrollHandler::setupScrolling(const TPoint& aNewPosition)
       
   284 {   
       
   285     if (m_lastPosition == TPoint(0, 0)) {
       
   286         m_lastPosition = aNewPosition;
       
   287     }
       
   288     if(m_lastPosition == aNewPosition)
       
   289         return; // no displacement -- means no need for scrolling    
       
   290 
       
   291     //Ignore move events until they jump the threshold (avoids jittery finger effect) 
       
   292     TInt absX = Abs( aNewPosition.iX - m_lastPosition.iX);
       
   293     TInt absY = Abs( aNewPosition.iY - m_lastPosition.iY);
       
   294     if( absX < KScrollThresholdPixels &&  absY < KScrollThresholdPixels)
       
   295         return;
       
   296             
       
   297     if (calculateScrollableFrameView(aNewPosition))  {
       
   298 
       
   299         // normalize current position to minimize cumulative rounding error 
       
   300         m_currentNormalizedPosition.iX = m_scrollableView.contentPos().iX * 100;
       
   301         m_currentNormalizedPosition.iY = m_scrollableView.contentPos().iY * 100;
       
   302         // do the scrolling in a time out
       
   303         m_scrollTimer->Cancel();                   
       
   304         m_scrollTimer->Start( 0, KScrollIntervalTimeout, TCallBack(&handleScrollTimerEventCallback,this));
       
   305         m_webView->setViewIsScrolling(true);
       
   306         m_webView->toggleRepaintTimer(false);
       
   307     }
       
   308 
       
   309 
       
   310 }    
       
   311 
       
   312 void WebPageScrollHandler::scrollContent()
       
   313 {
       
   314     TPoint scrollDelta = m_lastPosition - m_currentPosition;
       
   315  
       
   316     if(!m_scrollableView.activeFrameView())
       
   317             return;
       
   318         
       
   319     int absX = Abs(scrollDelta.iX);
       
   320     int absY = Abs(scrollDelta.iY);
       
   321                                        
       
   322     if(absX || absY) //move only if necessary
       
   323     {      
       
   324         // calculate which direction we are trying to scroll
       
   325         if(m_scrollDirectionState == ScrollDirectionUnassigned) {
       
   326             m_focalPoint = m_currentPosition;
       
   327             calculateScrollDirection(absX, absY);
       
   328         }   
       
   329         
       
   330         switch (m_scrollDirectionState)
       
   331         {           
       
   332             case ScrollDirectionX: //scroll in X dir
       
   333             {
       
   334                 scrollDelta.iY = 0;
       
   335                 scrollDelta.iX *= 100;
       
   336                 //Fallback to XY state if the current position is out of bounds                
       
   337                 TPoint boundaryCheckpoint = m_focalPoint - m_currentPosition;                                
       
   338                 if(Abs(boundaryCheckpoint.iY) > KScrollDirectionBoundary)
       
   339                     m_scrollDirectionState = ScrollDirectionXY;
       
   340                 break;
       
   341             }
       
   342             case ScrollDirectionY: //scroll in Y dir
       
   343             {                
       
   344                 scrollDelta.iX = 0;
       
   345                 scrollDelta.iY *= 100;
       
   346                 //Fallback to XY state if the current position is out of bounds                
       
   347                 TPoint boundaryCheckpoint = m_focalPoint - m_currentPosition;                                
       
   348                 if(Abs(boundaryCheckpoint.iX) > KScrollDirectionBoundary)
       
   349                     m_scrollDirectionState = ScrollDirectionXY;
       
   350                 break;
       
   351             }
       
   352             case ScrollDirectionXY: //scroll in XY
       
   353             {
       
   354                 scrollDelta.iX *= 100;
       
   355                 scrollDelta.iY *= 100;
       
   356                 m_scrollDirectionState = ScrollDirectionUnassigned;
       
   357                 break;
       
   358             }
       
   359         }        
       
   360         if (m_scrollableView.m_scrollingElement) {
       
   361             bool shouldScrollVertically = false;
       
   362             bool shouldScrollHorizontally = false;
       
   363             //WebFrameView* mfv = m_webView->mainFrame()->frameView();
       
   364             WebFrame* frame = kit(m_scrollableView.m_scrollingElement->document()->frame());
       
   365             IntPoint currPoint = frame->frameView()->viewCoordsInFrameCoords(m_currentPosition);
       
   366             RenderObject* render = m_scrollableView.m_scrollingElement->renderer();
       
   367             __ASSERT_DEBUG(render->isScrollable(), User::Panic(_L(""), KErrGeneral));
       
   368             if (scrollDelta.iY)
       
   369                 shouldScrollVertically = !render->scroll(ScrollDown, ScrollByPixel, frame->frameView()->toDocCoords(scrollDelta).iY / 100);
       
   370             if (scrollDelta.iX)
       
   371                 shouldScrollHorizontally = !render->scroll(ScrollRight, ScrollByPixel, frame->frameView()->toDocCoords(scrollDelta).iX / 100);
       
   372             TPoint scrollPos = frame->frameView()->contentPos();
       
   373             TPoint newscrollDelta = frame->frameView()->toDocCoords(scrollDelta);
       
   374             m_currentNormalizedPosition +=  newscrollDelta;     
       
   375 
       
   376             if (shouldScrollHorizontally) {
       
   377                 scrollPos.iX = m_currentNormalizedPosition.iX/100;
       
   378             }
       
   379             if (shouldScrollVertically) {
       
   380                 scrollPos.iY = m_currentNormalizedPosition.iY/100;
       
   381             }
       
   382             frame->frameView()->scrollTo(scrollPos);
       
   383             m_lastPosition = m_currentPosition;
       
   384             m_currentNormalizedPosition.iX = frame->frameView()->contentPos().iX * 100;
       
   385             m_currentNormalizedPosition.iY = frame->frameView()->contentPos().iY * 100;
       
   386             if (shouldScrollVertically || shouldScrollHorizontally)
       
   387                 updateScrollbars(scrollPos, newscrollDelta);
       
   388             currPoint = frame->frameView()->viewCoordsInFrameCoords(m_currentPosition);
       
   389             if (shouldScrollHorizontally || shouldScrollVertically) {
       
   390                 core(frame)->sendScrollEvent();
       
   391                 m_webView->DrawNow();
       
   392             }
       
   393         }
       
   394         else {
       
   395             TPoint scrollPos;
       
   396             TPoint newscrollDelta = m_scrollableView.m_frameView->toDocCoords(scrollDelta);
       
   397             m_currentNormalizedPosition +=  newscrollDelta;  
       
   398             scrollPos.iX = m_currentNormalizedPosition.iX/100;
       
   399             scrollPos.iY = m_currentNormalizedPosition.iY/100;
       
   400             TPoint cpos = m_scrollableView.m_frameView->contentPos();
       
   401            
       
   402             if(!m_scrollableView.m_frameView->needScroll(scrollPos)) {
       
   403                 m_scrollDirectionState = ScrollDirectionUnassigned;
       
   404                 m_lastPosition = m_currentPosition;
       
   405                 m_currentNormalizedPosition.iX = m_scrollableView.contentPos().iX * 100;
       
   406                 m_currentNormalizedPosition.iY = m_scrollableView.contentPos().iY * 100;
       
   407             }
       
   408             else {
       
   409                 m_scrollableView.m_frameView->scrollTo(scrollPos);
       
   410                 m_lastPosition = m_currentPosition;
       
   411 #ifndef BRDO_USE_GESTURE_HELPER                
       
   412                 m_decel->updatePos();
       
   413 #endif                
       
   414             // update scroll bars
       
   415                 updateScrollbars(scrollPos, newscrollDelta);
       
   416             }
       
   417         }
       
   418     }
       
   419 } 
       
   420 
       
   421 bool WebPageScrollHandler::calculateScrollableFrameView(const TPoint& aNewPosition)
       
   422 {
       
   423     if (calculateScrollableElement(aNewPosition)) return true;
       
   424     
       
   425     //First figure out the direction we are scrolling    
       
   426     bool x_r = false;
       
   427     bool x_l = false;
       
   428     bool y_t = false;
       
   429     bool y_b = false;
       
   430 
       
   431     //find the x direction
       
   432     int x_delta = aNewPosition.iX - m_lastPosition.iX;
       
   433     if (x_delta > 0) {
       
   434         x_l = true;                
       
   435     } else if (x_delta < 0){
       
   436         x_r = true;
       
   437     }
       
   438 
       
   439     //find the y direction
       
   440     int y_delta = aNewPosition.iY - m_lastPosition.iY;
       
   441     if (y_delta > 0) {
       
   442         y_t = true;                
       
   443     } else if (y_delta < 0){
       
   444         y_b = true;
       
   445     }
       
   446         
       
   447     m_scrollableView.m_frameView = NULL;
       
   448         
       
   449     //find the frame that can scroll if we can't scroll check the parents        
       
   450     WebFrame* frame = m_webView->mainFrame()->frameAtPoint(aNewPosition);
       
   451     for (; frame; frame = frame->parentFrame())  {
       
   452     
       
   453         // Dont scroll a frameset
       
   454         if (frame->parentFrame() && frame->parentFrame()->isFrameSet()) 
       
   455             continue;     
       
   456         
       
   457         TPoint contentpos = frame->frameView()->contentPos();
       
   458         TSize contentsize = frame->frameView()->contentSize();        
       
   459         TRect framerect = frame->frameView()->rect();        
       
   460         
       
   461         //if the content width is > frameview width
       
   462         if (contentsize.iWidth > framerect.Width() && frame->frameView()->hScrollbar()->isEnabled()) {
       
   463             //IF we are trying to scroll to the right we need 
       
   464             //to see if the content position < content size - frameview size        
       
   465             //ELSE if we are trying to the left we need 
       
   466             //to see if the content position > 0 
       
   467             if (x_r) {        
       
   468                 if (contentpos.iX < (contentsize.iWidth - framerect.Width())) {
       
   469                     m_scrollableView.m_frameView = frame->frameView();
       
   470                     return true;                
       
   471                 }
       
   472 
       
   473             } else if (x_l) {
       
   474                 if (contentpos.iX > 0) {
       
   475                     m_scrollableView.m_frameView = frame->frameView();
       
   476                     return true;                
       
   477                 }            
       
   478             }
       
   479         }
       
   480         
       
   481         //if the content height is > frameview height
       
   482         if (contentsize.iHeight > framerect.Height() && frame->frameView()->vScrollbar()->isEnabled()) {
       
   483             //IF we are trying to scroll down we need 
       
   484             //to see if the content position < content size - frameview size        
       
   485             //ELSE if we are trying to scroll up we need 
       
   486             //to see if the content position > 0 
       
   487             if (y_b) {        
       
   488                 if (contentpos.iY < (contentsize.iHeight - framerect.Height())) {
       
   489                     m_scrollableView.m_frameView = frame->frameView();
       
   490                     return true;                
       
   491                 }
       
   492 
       
   493             } else if (y_t) {
       
   494                 if (contentpos.iY > 0) {
       
   495                     m_scrollableView.m_frameView = frame->frameView();
       
   496                     return true;                
       
   497                 }            
       
   498             }
       
   499         }
       
   500     }
       
   501     
       
   502     //could not find a scrollable frame        
       
   503     m_scrollableView.m_frameView  = m_webView->mainFrame()->frameView();
       
   504     return true;
       
   505    
       
   506 }
       
   507 
       
   508 void WebPageScrollHandler::calculateScrollDirection(int absX, int absY)
       
   509 {
       
   510      //assign scroll direction state according to scroll angle
       
   511     if((absX * KAngularDeviationThreshold) < (absY * 100))
       
   512         m_scrollDirectionState = ScrollDirectionY;
       
   513     else if((absY * KAngularDeviationThreshold) < (absX * 100))
       
   514         m_scrollDirectionState = ScrollDirectionX;
       
   515     else
       
   516         m_scrollDirectionState = ScrollDirectionXY;    
       
   517 }
       
   518 
       
   519 void WebPageScrollHandler::updateScrollbars(const TPoint& scrollPos, TPoint& newscrollDelta)
       
   520 {
       
   521     WebFrameView* fv = m_scrollableView.activeFrameView();
       
   522     if (fv) {
       
   523         
       
   524         if (fv->vScrollbar()) {
       
   525             fv->vScrollbar()->setValue(scrollPos.iY);
       
   526         }
       
   527 
       
   528         if (fv->hScrollbar()) {
       
   529             fv->hScrollbar()->setValue(scrollPos.iX);
       
   530         }
       
   531         
       
   532         if ((fv->frame() == m_webView->mainFrame())) {
       
   533           m_scrollbarDrawer->drawScrollbar(m_webView, newscrollDelta);
       
   534         }
       
   535     }
       
   536 }
       
   537          
       
   538 
       
   539 bool WebPageScrollHandler::calculateScrollableElement(const TPoint& aNewPosition)
       
   540 {
       
   541     WebFrame* frame = m_webView->mainFrame()->frameAtPoint(aNewPosition);
       
   542     if( !frame ) return false;
       
   543     TPoint pt = frame->frameView()->viewCoordsInFrameCoords(aNewPosition);
       
   544     Element* e = core(frame)->document()->elementFromPoint(pt.iX, pt.iY);
       
   545     Element* currElement = NULL;
       
   546     if(!e) return NULL;
       
   547     RenderObject* render = e->renderer();
       
   548     if (render && render->isScrollable()) {
       
   549         RenderLayer* layer = render->enclosingLayer();
       
   550         Element* parent = e;
       
   551         currElement = e;
       
   552         while (!currElement->isControl() && parent && parent->renderer() && parent->renderer()->enclosingLayer() == layer) {
       
   553             currElement = parent;
       
   554             Node* pn = parent;
       
   555             do {
       
   556                 pn = pn->parent();
       
   557             } while (pn && !pn->isElementNode());
       
   558             parent = static_cast<Element*>(pn);
       
   559         }
       
   560         if (currElement) {
       
   561             currElement->ref();
       
   562             m_scrollableView.m_scrollingElement = currElement; 
       
   563             m_scrollableView.m_frameView = NULL;
       
   564             return true;
       
   565         }
       
   566     }
       
   567     return false;
       
   568 }
       
   569 
       
   570 
       
   571 void WebPageScrollHandler::scrollPageOverviewGH()
       
   572 {
       
   573 
       
   574     TRect indicatorRect = m_webView->pageScaler()->IndicatorRect();
       
   575     TInt zoomLevel = m_webView->pageScaler()->ZoomOutLevel();
       
   576     TPoint currentPosition = m_webView->mainFrame()->frameView()->contentPos();
       
   577     TInt xInDoc = ((m_currentPosition.iX - indicatorRect.iTl.iX  - indicatorRect.Width() / 2) * zoomLevel ) / 100 + currentPosition.iX;
       
   578     TInt yInDoc = ((m_currentPosition.iY - indicatorRect.iTl.iY  - indicatorRect.Height() / 2) * zoomLevel ) / 100 + currentPosition.iY;
       
   579            
       
   580     m_webView->mainFrame()->frameView()->scrollTo(TPoint(xInDoc, yInDoc));    
       
   581 
       
   582 }
       
   583 
       
   584 
       
   585 void WebPageScrollHandler::handleScrollingGH(const MGestureEvent& aEvent)
       
   586 {   
       
   587     TPoint newPos = aEvent.CurrentPos();
       
   588     m_currentPosition = newPos;
       
   589     if (m_webView->inPageViewMode()) {
       
   590         if (!m_pageOverviewScrollPeriodic->IsActive()){
       
   591             m_pageOverviewScrollPeriodic->Start( 0, KPageOverviewScrollPeriodic, 
       
   592                                                 TCallBack(&pageOverviewScrollCallback, this));
       
   593             m_webView->setViewIsScrolling(true);
       
   594             m_webView->toggleRepaintTimer(false);
       
   595         }
       
   596     }
       
   597     else if (!m_webView->viewIsScrolling()) {
       
   598         setupScrolling(newPos);    
       
   599     }
       
   600 }
       
   601 
       
   602 
       
   603 void WebPageScrollHandler::handleTouchDownGH(const MGestureEvent& aEvent)
       
   604 {
       
   605     TPoint newPos = aEvent.CurrentPos();
       
   606     m_lastMoveEventTime = 0; 
       
   607     m_lastPosition = newPos;
       
   608     m_currentPosition = newPos;
       
   609     m_webView->setViewIsScrolling(false);      
       
   610     m_webView->toggleRepaintTimer(true);
       
   611             
       
   612     if (m_decelGH) {
       
   613         m_decelGH->cancelDecel();
       
   614     }
       
   615     m_scrollableView.m_scrollingElement = NULL;
       
   616     m_scrollableView.m_frameView = NULL;
       
   617 }
       
   618 
       
   619 
       
   620 void WebPageScrollHandler::handleTouchUpGH(const MGestureEvent& aEvent)
       
   621 {
       
   622     bool decelDoesScrollbars = false;
       
   623     TPoint newPos = aEvent.CurrentPos();
       
   624 
       
   625     if (m_webView->inPageViewMode()) {
       
   626         if (m_pageOverviewScrollPeriodic->IsActive()){ 
       
   627             m_pageOverviewScrollPeriodic->Cancel();
       
   628         }
       
   629         m_webView->closePageView();
       
   630         scrollPageOverviewGH();
       
   631         m_webView->setViewIsScrolling(false);
       
   632         m_webView->toggleRepaintTimer(true);
       
   633     }
       
   634     else {
       
   635         m_scrollTimer->Cancel();
       
   636         m_lastPosition = TPoint(0, 0);
       
   637         if (m_scrollableView.m_scrollingElement) {
       
   638             if (m_scrollableView.m_scrollingElement) {
       
   639                 m_scrollableView.m_scrollingElement->deref();
       
   640                 m_scrollableView.m_scrollingElement = NULL;
       
   641             }
       
   642         }
       
   643         else {
       
   644             decelDoesScrollbars = startDeceleration(aEvent);
       
   645                     
       
   646             if (m_webView->viewIsScrolling()) {
       
   647                 Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
       
   648                 frame->bridge()->sendScrollEvent();                            
       
   649             }
       
   650         }
       
   651     
       
   652         if (!decelDoesScrollbars) {
       
   653             m_scrollbarDrawer->fadeScrollbar();
       
   654             m_webView->setViewIsScrolling(false);
       
   655             m_webView->toggleRepaintTimer(true);
       
   656         }
       
   657         m_scrollDirectionState = ScrollDirectionUnassigned;
       
   658         m_lastMoveEventTime = 0;
       
   659     }
       
   660 }
       
   661 
       
   662 
       
   663 bool WebPageScrollHandler::startDeceleration(const MGestureEvent& aEvent)
       
   664 {
       
   665     bool started = false;
       
   666     TRealPoint gstSpeed = aEvent.Speed();
       
   667     if (Abs(gstSpeed.iX / gstSpeed.iY) <= KTanOfThresholdAngle) {
       
   668        gstSpeed.iX = 0;
       
   669     }
       
   670     
       
   671     if (Abs(gstSpeed.iY / gstSpeed.iX) <= KTanOfThresholdAngle) { 
       
   672        gstSpeed.iY = 0;
       
   673     }
       
   674     
       
   675     if ((Abs(gstSpeed.iX) > 0) || (Abs(gstSpeed.iY) > 0)) {
       
   676        m_decelGH->startDecel(gstSpeed, m_scrollbarDrawer); 
       
   677        started = true;
       
   678     }
       
   679     
       
   680     
       
   681     return started;
       
   682 }
       
   683 
       
   684 //  End of File