diff -r 9ba538e329bd -r 7d9067c6fcb1 photosgallery/viewframework/views/cloudview/src/glxcloudviewcontrol.cpp --- a/photosgallery/viewframework/views/cloudview/src/glxcloudviewcontrol.cpp Thu Jan 07 12:46:23 2010 +0200 +++ b/photosgallery/viewframework/views/cloudview/src/glxcloudviewcontrol.cpp Mon Jan 18 20:19:20 2010 +0200 @@ -33,7 +33,7 @@ #include // For CAlfDisplay #include // For alfScrollbar model #include - +#include // For Kinetic Scrolling #include #include #include @@ -65,8 +65,9 @@ const TInt KRightmargin = 20; const TInt KMinTagSize = 77; const TInt KTagScreenHeight = 460; -const TInt KDragHoldTime = 500; - +const TReal KBoundaryMargin = 0.1; //10% = 10/100 = 0.1 +const TInt KFastCloudMovement = 100; //Transition time to move cloud view +const TInt KSlowCloudMovement = 1000; //Transition time to move cloud view // --------------------------------------------------------------------------- // Two-phased constructor. @@ -142,7 +143,7 @@ iParentLayout = CAlfLayout::AddNewL(*this, aAnchorLayout); iTagScreenWidth = rect.Width() - iScrollPaneHandle.iW - KRightmargin; - if (GlxGeneralUiUtilities::IsLandscape()) + if(IsLandscape()) { iTagScreenHeight = rect.Height(); } @@ -194,6 +195,8 @@ } //get touch feedback instance iTouchFeedback = MTouchFeedback::Instance(); + iPhysics = CAknPhysics::NewL(*this, NULL); + InitPhysicsL(); } @@ -206,10 +209,10 @@ TRACER("GLX_CLOUD::CGlxCloudViewControl::VisualLayoutUpdated"); TRect rect; AknLayoutUtils::LayoutMetricsRect (AknLayoutUtils::EMainPane, rect); - if ( (rect.Width() != iTagScreenWidth) && ( rect.Height () != iScreenHeight)) + if ((rect.Width() != (iTagScreenWidth + iScrollPaneHandle.iW + KRightmargin)) || (rect.Height() != iScreenHeight)) { //set the new screen dimensions - UpdateLayoutL(); + TRAP_IGNORE(UpdateLayoutL()); } } @@ -237,6 +240,7 @@ iUiUtility->Close (); } delete iEmptyText; + delete iPhysics; } // --------------------------------------------------------------------------- @@ -408,7 +412,7 @@ iViewPortLayout->SetSize(TAlfRealSize(iTagScreenWidth,iTagScreenHeight), 0); iViewPortSize.iWidth = iTagScreenWidth; iViewPortSize.iHeight = iTagScreenHeight; - iViewPortLayout->SetViewportPos(TAlfRealPoint(0, 0),1000); + iViewPortLayout->SetViewportPos(TAlfRealPoint(0, 0), KSlowCloudMovement); iViewPortPosition.iX =0; iViewPortPosition.iY =0; @@ -475,7 +479,7 @@ case EKeyDownArrow: { - if(iCloudInfo.Count() >1 ) + if (iCloudInfo.Count() > 1) { HandleKeyDownL (); consumed = ETrue; @@ -594,35 +598,6 @@ //if its a pointer event consumed = HandlePointerEventL(aEvent); } - else if( aEvent.IsCustomEvent() ) - { - if(aEvent.CustomParameter() == ECustomEventFocusDragScroll) - { - //dragging down - if( iIsDragging == 1 ) - { - if(iFocusRowIndex!=iCloudInfo.Count()-1) - { - SetRelativeFocusL(iFocusRowIndex+1); - iFocusRowIndex = RowNumber (iMediaList.FocusIndex ()); - // iScrollDirection = 0; - MoveDownIfRequired(); - } - } - //dragging up - else if(iIsDragging == 2) - { - if(iFocusRowIndex!=0) - { - SetRelativeFocusL(iFocusRowIndex-1); - iFocusRowIndex = RowNumber (iMediaList.FocusIndex ()); - // iScrollDirection = 0; - MoveUpIfRequired(); - } - } - } - consumed = EFalse; - } return consumed; } @@ -663,10 +638,9 @@ // If the last item is focused and if we are navigating downwards,then set the // focus to first element. - if( iFocusRowIndex == iCloudInfo.Count()-1 ) - { - iMediaList.SetFocusL (NGlxListDefs::EAbsolute, - 0); + if (iFocusRowIndex == iCloudInfo.Count() - 1) + { + iMediaList.SetFocusL(NGlxListDefs::EAbsolute, 0); } //else set the focus to the item which is in the next row,that overlaps with midpoint of the @@ -818,6 +792,7 @@ UpdateRowDataL (); //updates the row data and reassigns font sizes and draw the layout on screen. } + InitPhysicsL(); } @@ -859,6 +834,7 @@ DisplayEmptyCloudViewL(); } } + InitPhysicsL(); } // --------------------------------------------------------------------------- @@ -910,6 +886,8 @@ } //generate row structures and draw rows on screen UpdateRowDataL (); + + InitPhysicsL(); } } @@ -1336,7 +1314,7 @@ { iViewPortPosition.iY = iViewPortVirtualSize.iHeight - iViewPortSize.iHeight; } - iViewPortLayout->SetViewportPos (iViewPortPosition,1000); + iViewPortLayout->SetViewportPos(iViewPortPosition, KSlowCloudMovement); iScrollEventData.mViewStartPos = iViewPortPosition.iY; Scroll(); //CalculateBubleMidPoint (); @@ -1371,7 +1349,7 @@ { iViewPortPosition.iY = 0; } - iViewPortLayout->SetViewportPos (iViewPortPosition,1000); + iViewPortLayout->SetViewportPos(iViewPortPosition, KSlowCloudMovement); iScrollEventData.mViewStartPos = iViewPortPosition.iY; if(iScrollBarWidget) { @@ -1434,8 +1412,21 @@ TRACER("GLX_CLOUD::CGlxCloudViewControl::HandlePointerEventL"); CAlfVisual* tappedvisual = aEvent.Visual(); TBool consumed = EFalse; + if(aEvent.PointerEvent().iType == TPointerEvent::EButton1Down) { + //reset variables & Physics simulator + iPhysics->StopPhysics(); + iPhysics->ResetFriction(); + iDragging = EFalse; + iPhysicsStarted = EFalse; + iStartTime.HomeTime(); + iViewDragged = EFalse; + Display()->Roster().SetPointerEventObservers( + EAlfPointerEventReportDrag + EAlfPointerEventReportLongTap + + EAlfPointerEventReportUnhandled, *this); + Display()->Roster().DisableLongTapEventsWhenDragging(*this); + if(tappedvisual) { for(TInt index=0;indexCount();index++) @@ -1445,19 +1436,53 @@ if(layoutvisual == tappedvisual) { TInt focus = iMediaList.FocusIndex(); - //if the visual is already focused then for next tap open the next view - if( focus == index ) + if (index != focus) { - iTouchFeedback->InstantFeedback( ETouchFeedbackBasic ); - iObserverEnterKeyEvent.HandleEnterKeyEventL( (TInt)EAknCmdOpen ); - consumed = ETrue; + iTouchFeedback->InstantFeedback(ETouchFeedbackBasic); + iMediaList.SetFocusL(NGlxListDefs::EAbsolute, index); + SetFocusColor(); } - else if( index!= focus ) + consumed = ETrue; + break; + } + } + } + } + else if (aEvent.PointerEvent().iType == TPointerEvent::EDrag) + { + GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::HandlePointerEventL(EDrag) event"); + iTouchFeedback->InstantFeedback(ETouchFeedbackBasic); + + consumed = HandleDragL(aEvent.PointerEvent()); + } + else if (aEvent.PointerUp()) + { + Display()->Roster().SetPointerEventObservers(0, *this); + consumed = ETrue; + + //Check if dragging actually happened using iViewDragged + if (iDragging && iViewDragged) + { + iDragging = EFalse; + TPoint drag = iStart - aEvent.PointerEvent().iPosition; + iPhysics->StartPhysics(drag, iStartTime); + iPhysicsStarted = ETrue; + } + //If dragging not happened consider it as Tapped event + else if (tappedvisual && !iViewDragged) + { + for (TInt index = 0; index < iLayout->Count(); index++) + { + CAlfVisual* layoutvisual = &(iLayout->Visual(index)); + //if the tapped visual is same as the visual in the layout then focus that visual + if (layoutvisual == tappedvisual) + { + TInt focus = iMediaList.FocusIndex(); + if (index != focus) { iTouchFeedback->InstantFeedback( ETouchFeedbackBasic ); TInt focusrowindex = iFocusRowIndex; - iMediaList.SetFocusL (NGlxListDefs::EAbsolute, - index); + iMediaList.SetFocusL(NGlxListDefs::EAbsolute, index); SetFocusColor(); iFocusRowIndex = RowNumber (iMediaList.FocusIndex ()); if( iFocusRowIndex > focusrowindex) @@ -1473,29 +1498,15 @@ MoveUpIfRequired(); } } + + iTouchFeedback->InstantFeedback(ETouchFeedbackBasic); + iObserverEnterKeyEvent.HandleEnterKeyEventL((TInt) EAknCmdOpen); consumed = ETrue; - Display()->Roster().SetPointerEventObservers( EAlfPointerEventReportDrag - + EAlfPointerEventReportLongTap - + EAlfPointerEventReportUnhandled, *this ); - Display()->Roster().DisableLongTapEventsWhenDragging(*this); break; } } } - } - - else if (aEvent.PointerEvent().iType == TPointerEvent::EDrag) - { - GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::HandlePointerEventL(EDrag) event"); - iTouchFeedback->InstantFeedback( ETouchFeedbackBasic ); - consumed = HandleDragL(aEvent.PointerEvent()); - } - else if (aEvent.PointerUp()) - { - - Env().CancelCustomCommands(this,ECustomEventFocusDragScroll); - Display()->Roster().SetPointerEventObservers(0, *this); - consumed = ETrue; + iViewDragged = EFalse; } return consumed; } @@ -1506,59 +1517,65 @@ // TBool CGlxCloudViewControl::HandleDragL(const TPointerEvent& aPointerEvent) { - TRACER("GLX_CLOUD::CGlxCloudViewControl::HandleDragL"); - TBool consumed = EFalse; - TInt itemindex = GetAbsoluteIndex(aPointerEvent.iPosition); - TInt focus = iMediaList.FocusIndex(); - TInt focusrowindex = iFocusRowIndex; + TBool consumed(EFalse); + + // If Physics Emulation is going on, no need to entertain drag event + if (iPhysicsStarted) + return consumed; - //if index is not NULL then focus the tag and move the viewport down if necessary - if ( itemindex != KErrNotFound ) + //Simply ignore the first drag event as there is huge difference between position + //coordinates in drag event and corordinates in normal pointer down / up events + if (!iDragging) { - if (focus != itemindex ) - { - iTouchFeedback->InstantFeedback( ETouchFeedbackSensitive ); - iMediaList.SetFocusL (NGlxListDefs::EAbsolute,itemindex); - iFocusRowIndex = RowNumber (iMediaList.FocusIndex ()); - GLX_LOG_INFO1("GLX_CLOUD :: CGlxCloudViewControl::HandleDragL,focusrowindex = %d",iFocusRowIndex); - if( iFocusRowIndex > focusrowindex) - { - GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::HandleDragL,b4 movedown"); - iScrollDirection = 0; - MoveDownIfRequired(); - } - else if( iFocusRowIndex < focusrowindex ) - { - GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::HandleDragL,b4 moveup"); - iScrollDirection = 1; - MoveUpIfRequired(); - } - } - consumed = ETrue; + //Note the current position for future reference + iStart = aPointerEvent.iPosition; + iPrev = iStart; + iDragging = ETrue; + return consumed; } - TRect screenstartrect; - //the starting rect of the visible screen - screenstartrect.SetRect(0,0,iTagScreenWidth,2*KRowHeight); + TRect rect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, rect); + TInt cntrlTopYLimit = rect.iTl.iY; + TInt cntrlBottomYLimit = rect.iBr.iY; + TInt delta = iPrev.iY - aPointerEvent.iPosition.iY; - TRect screenendrect; - //the end rect of the visible screen - screenendrect.SetRect(0,(iTagScreenHeight-(2*KRowHeight)),iTagScreenWidth,iTagScreenHeight); + //Check for physics threshold, before regidterting drag corordinates + TInt deltaAbs = delta < 0 ? -delta : delta; + TBool panning = deltaAbs >= iPhysics->DragThreshold(); + if (panning) + { + TPoint deltaPt = iPrev - aPointerEvent.iPosition; + iPhysics->RegisterPanningPosition(deltaPt); + iPrev = aPointerEvent.iPosition; + iViewDragged = ETrue; + } + consumed = ETrue; - //dragging down - if(screenendrect.Contains(aPointerEvent.iPosition)) - { - iIsDragging = 1; - Env().Send(TAlfCustomEventCommand(ECustomEventFocusDragScroll, - this),KDragHoldTime); + //Calculate margin after which we might get pointer out of screen, and we might not + //get further pointer events. Also This is currently only 10% of total delta we can find, + //to get margin corresponding to movement of user flicking speed + //This implies higher speed - higher margin + //Lower speed - 0 margin + TInt deltaMargin = deltaAbs * KBoundaryMargin; + + //Code to predict future movement if same delta movement we might get in future + //For flick event down - If the movement goes below screen, start physics + //or For flick event up - If the movement goes above screen, start physics + if (((delta < 0) && (aPointerEvent.iPosition.iY - delta >= cntrlBottomYLimit - deltaMargin)) + || ((delta > 0) && (aPointerEvent.iPosition.iY - delta <= cntrlTopYLimit + deltaMargin))) + { + iPhysicsStarted = ETrue; } - //dragging up - else if (screenstartrect.Contains(aPointerEvent.iPosition)) + + //If found that possibly in next move it might go out of bounds, start physics + //emulation + if (iPhysicsStarted && iDragging) { - iIsDragging = 2; - Env().Send(TAlfCustomEventCommand(ECustomEventFocusDragScroll, - this),KDragHoldTime); - } + TPoint drag = iStart - aPointerEvent.iPosition; + iPhysics->StartPhysics(drag, iStartTime); + iDragging = EFalse; + } return consumed; } @@ -1684,6 +1701,8 @@ TInt steps = TInt(aEvent.CustomEventData()); UpdateScrollBar(steps,EFalse); Scroll(); + iPhysics->StopPhysics(); + status = EEventHandled; } break; @@ -1692,7 +1711,8 @@ GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::offerEvent(EEventScrollPageUp) event"); UpdateScrollBar(-iScrollEventData.mViewLength); Scroll(); - status = EEventHandled; + iPhysics->StopPhysics(); + status = EEventHandled; } break; case EEventScrollPageDown: @@ -1700,6 +1720,7 @@ GLX_LOG_INFO("GLX_CLOUD :: CGlxCloudViewControl::offerEvent(EEventScrollPageDown) event"); UpdateScrollBar(iScrollEventData.mViewLength); Scroll(); + iPhysics->StopPhysics(); status = EEventHandled; } break; @@ -1755,7 +1776,7 @@ iScrollbarElement->offerEvent(*(iScrollBarWidget->control()),customevent); GLX_LOG_INFO1("GLX_CLOUD ::CGlxCloudViewControl::Scroll(),position %d ",iScrollEventData.mViewStartPos); iViewPortPosition.iY = iScrollEventData.mViewStartPos; - iViewPortLayout->SetViewportPos (iViewPortPosition,1000); + iViewPortLayout->SetViewportPos(iViewPortPosition, KSlowCloudMovement); } // --------------------------------------------------------------------------- @@ -1820,12 +1841,12 @@ { TRect rect; AknLayoutUtils::LayoutMetricsRect (AknLayoutUtils::EMainPane, rect); - if ( (rect.Width() != iTagScreenWidth) && ( rect.Height () != iScreenHeight)) + if ((rect.Width() != (iTagScreenWidth + iScrollPaneHandle.iW + KRightmargin)) || (rect.Height() != iScreenHeight)) { //set the new screen dimensions iScreenHeight=rect.Height(); iTagScreenWidth = rect.Width()- iScrollPaneHandle.iW - KRightmargin; - if (GlxGeneralUiUtilities::IsLandscape()) + if(IsLandscape()) { iTagScreenHeight = rect.Height(); } @@ -1842,8 +1863,79 @@ FetchAttributeFromCacheL(); //generate row structures and draw rows on screen UpdateRowDataL (); + + InitPhysicsL(); } } } + +// --------------------------------------------------------------------------- +// InitPhysicsL() +// --------------------------------------------------------------------------- +// +void CGlxCloudViewControl::InitPhysicsL() + { + //Update physics with new total layout, viewable size and our landscape mode + iPhysics->InitPhysicsL(TSize(iViewPortVirtualSize.iWidth, + iViewPortVirtualSize.iHeight), TSize(iTagScreenWidth, + iTagScreenHeight), EFalse); + + //Note: Physics viewposition must always be mid of viewable screen size to get best result + //I learned the hard way + iViewPosition.SetXY(iTagScreenWidth / 2, iTagScreenHeight / 2); + } + +// --------------------------------------------------------------------------- +// ViewPositionChanged() +// --------------------------------------------------------------------------- +// +void CGlxCloudViewControl::ViewPositionChanged(const TPoint& aNewPosition, + TBool aDrawNow, TUint /*aFlags*/) + { + iViewPosition = aNewPosition; + iViewPortPosition.iY = iViewPosition.iY - iTagScreenHeight / 2; + if (aDrawNow) + { + iViewPortLayout->SetViewportPos(iViewPortPosition, KFastCloudMovement); + iScrollEventData.mViewStartPos = iViewPortPosition.iY; + Scroll(); + } + } + +// --------------------------------------------------------------------------- +// PhysicEmulationEnded() +// --------------------------------------------------------------------------- +// +void CGlxCloudViewControl::PhysicEmulationEnded() + { + iPhysicsStarted = EFalse; + } + +// --------------------------------------------------------------------------- +// ViewPosition() +// --------------------------------------------------------------------------- +// +TPoint CGlxCloudViewControl::ViewPosition() const + { + return iViewPosition; + } + +// --------------------------------------------------------------------------- +// IsLandscape() +// --------------------------------------------------------------------------- +// +TBool CGlxCloudViewControl::IsLandscape() + { + TRect rect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, rect); + if(rect.Width() > rect.Height()) + { + return ETrue; + } + else + { + return EFalse; + } + } //End of file