ui/widgets/glxzoomwidget/src/glxzoomwidget.cpp
changeset 61 743eb0b9959e
parent 55 fb37077c270f
child 67 199e6e1e0b54
--- a/ui/widgets/glxzoomwidget/src/glxzoomwidget.cpp	Wed Aug 18 09:48:53 2010 +0300
+++ b/ui/widgets/glxzoomwidget/src/glxzoomwidget.cpp	Thu Sep 02 20:26:45 2010 +0300
@@ -24,6 +24,12 @@
 #include "glxmodelparm.h"
 #include "glxzoomwidget.h"
 
+const int MAXZVALUE = 100;
+const int MINZVALUE = 0;
+const int NOOFSTEPSZI = 24;
+const int NOOFSTEPSZO = 18;
+const float MAXDTZOOMIN = 3.5;
+
 GlxZoomWidget::GlxZoomWidget(QGraphicsItem *parent):HbScrollArea(parent), 
             mModel(NULL), mMinZValue(MINZVALUE), 
             mMaxZValue(MAXZVALUE), mTimerId(0),
@@ -34,7 +40,7 @@
     grabGesture(Qt::PinchGesture);
     grabGesture(Qt::TapGesture);
     setAcceptTouchEvents(true) ;
-    setFrictionEnabled(false);
+    setFrictionEnabled(true);
     setZValue(mMinZValue);
     //create the child items and background
     mZoomWidget = new QGraphicsWidget(this);
@@ -51,7 +57,8 @@
     //initializing the image decoder
     mImageDecoder = new GlxImageDecoderWrapper;
 
-	
+    setVerticalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff);
+    setHorizontalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff);
 	//AA: signal and slot to perform double tap animation
     //after every step redraw, signal is emitted to perform the next step
 	connect( this, SIGNAL( stepZoom() ), this, SLOT( animateDoubleTap() ), Qt::QueuedConnection );
@@ -183,7 +190,7 @@
          if(QTapGesture *gesture = static_cast<QTapGesture *>(event->gesture(Qt::TapGesture))) {        
             if (gesture->state() == Qt::GestureFinished) {
                 if(!mTimerId) {
-                    mTimerId = startTimer(500);
+                    mTimerId = startTimer( DOUBLETAP_TIMEINTERVAL );
                 }
             else {
                 killTimer(mTimerId);
@@ -203,13 +210,7 @@
        if (changeFlags & QPinchGesture::ScaleFactorChanged) {
             mPinchGestureOngoing = true;
             mZoomOngoing = true;
-            //bring the zoom widget to foreground
-            setZValue(mMaxZValue);
-            //show the black background
-            mBlackBackgroundItem->setParentItem(parentItem());
-            mBlackBackgroundItem->setZValue(mMaxZValue - 1);
-            mBlackBackgroundItem->show();
-
+            
             //retreive the gesture values
             qreal value = pinchG->scaleFactor() / pinchG->lastScaleFactor();
             QPointF center = pinchG->property("centerPoint").toPointF();
@@ -220,10 +221,15 @@
         }
        if (pinchG->state() == Qt::GestureStarted) {
            emit pinchGestureReceived(mFocusIndex);
+           //bring the zoom widget to foreground
+            setZValue(mMaxZValue);
+            //show the black background
+            mBlackBackgroundItem->setParentItem(parentItem());
+            mBlackBackgroundItem->setZValue(mMaxZValue - 1);
+            mBlackBackgroundItem->show();
        }
 
        if (pinchG->state() == Qt::GestureFinished) {
-           if(mStepCurrentSize != mCurrentSize) {
                //For giving a spring effect when user has zoomed more than normal.
                if(mStepCurrentSize.width() > mMaxScaleDecSize.width())   {
                    //scale the image to limited size
@@ -235,7 +241,7 @@
                mPinchGestureOngoing = false;
                 //finalize the transforms to the geometry else panning will not work
                 finalizeWidgetTransform();
-           }
+       
 //push the Zoom widget to background when zoomed image size nears FS image
            if(mStepCurrentSize.width() <= mMinDecScaleSize.width()*1.3)  {
                mBlackBackgroundItem->hide();
@@ -294,94 +300,79 @@
 //makes sure that the gesture is on the screen center if the image is smaller than the screen
 void GlxZoomWidget::adjustGestureCenter(QPointF & gestureCenter, qreal& zoomFactor)
 {
-    /* commenting this tweak, not necessary, needs to be reimplemented for pinch: IN progress
-    if(zoomFactor > 1 &&zoomFactor > 1.2 )  {
+    
+    //clip zoom factor for pinch zoom. Double tap zoomfactor should never exceed
+    //1.2 or 0.8 in any given step  
+/*    if(zoomFactor > 1.2 )  {
         zoomFactor = 1.2;
     }
-
-    if(zoomFactor < 1 &&zoomFactor < 0.8 )   {
+    if(zoomFactor < 0.7 )   {
         zoomFactor = 0.8;
-    }
-	*/
-    QSizeF requiredSize(mCurrentSize.width()*zoomFactor, mCurrentSize.height()*zoomFactor);
-    //keep smaller image centered
-    if(mCurrentSize.width() <= mWindowSize.width() )
-    {
-        gestureCenter.setX(mWindowSize.width()/2);
+    }*/
+
+    qDebug("AA::adjustGestureCenter::ZoomFactor (%f)",zoomFactor);
+    QPointF itemOriginPos = mZoomWidget->sceneTransform().map(QPointF(0,0)); 
+    QPointF gesCenter = mZoomWidget->sceneTransform().map(gestureCenter); 
 
-    }
-    if(mCurrentSize.height() <= mWindowSize.height())
-    {
-        gestureCenter.setY(mWindowSize.height()/2);
-
+    
+    //keep smaller image centered irrespective of zoomin or zoom out
+    //note, only if the image is smaller than window size, else preserve the 
+    //gesture center. Adjustments need to be done for both height/width
+    //only one of them will be applicable, unless the image is smaller than
+    //fullscreen size on both dimensions
+    if( (mCurrentSize.width() <= mWindowSize.width()))  {
+       //requires adjustment only in portrait orientation 
+       if(mWindowSize.width() > mWindowSize.height())
+           gestureCenter.setX(mWindowSize.width()/2);
     }
-    //maintains the boundary of the edges for zoom out conditions
-    if(zoomFactor < 1) {
-        QPointF itemOriginPos = mZoomWidget->sceneTransform().map(QPointF(0,0));
-        bool hasWidthExceededWindow = mCurrentSize.width() > mWindowSize.width();
-        bool hasHeightExceededWindow = mCurrentSize.height() > mWindowSize.height();
-        if(hasWidthExceededWindow) {
-            bool hasItemCrossedBoundary = false;
-            if(itemOriginPos.x() >= -5)  {
-                //image has crossed left boundry leaving blank space
-                //stick the gesture to the left corner
-                gestureCenter.setX(itemOriginPos.x());
-                hasItemCrossedBoundary = true;
+    //handle the case when CurrentSize is grater than window size
+    //this applies to zoomout flow
+    else  {
+        //when the image is positioned beyond the left edge of the window
+        //clamp the image to left edge
+        if(itemOriginPos.x() >= 0) {
+            gestureCenter.setX(itemOriginPos.x());    
+        }
+        //same applies when the image needs clamping on right edge
+        else if(itemOriginPos.x()+ mCurrentSize.width() <= mWindowSize.width()){
+            gestureCenter.setX(itemOriginPos.x() + mCurrentSize.width());
+        }
+        //else no clamping is required, theg esture center can be preserved
+        //as is for the zoom step
+   }
+        
+    //same logic applied for Y axis
+    if( (mCurrentSize.height() <= mWindowSize.height())  )  {
+        //requires adjustment only in landscape orientation
+        if(mWindowSize.width() < mWindowSize.height())
+                   gestureCenter.setY(mWindowSize.height()/2);
+    }     
+    else  {
+            if(itemOriginPos.y() >= 0) {
+               gestureCenter.setY(itemOriginPos.y());    
             }
-        
-            //Check if the right boundry can be adjusted
-            if(itemOriginPos.x()+ mCurrentSize.width() <= mWindowSize.width()+5) {
-                //Image is before the right boundry leaving blank space
-                gestureCenter.setX(itemOriginPos.x()+ mCurrentSize.width() );
-                hasItemCrossedBoundary = true;
-            }
-            if((mCurrentSize.width() - mWindowSize.width() <= 20) && !hasItemCrossedBoundary) {
-                gestureCenter.setX(mWindowSize.width()/2 + (qAbs(itemOriginPos.x()) - 10));
+            else if(itemOriginPos.y()+ mCurrentSize.height() <= mWindowSize.height()){
+                gestureCenter.setY(itemOriginPos.y() + mCurrentSize.height());
             }
         }
-
-        if(hasHeightExceededWindow) {
-             bool hasItemCrossedBoundary = false;
-            //check if the upper boundry could be adjusted
-            if(itemOriginPos.y() >= -5) {
-                //image has crossed the upper boundry leaving blank space
-                //stick the image to the upper boundry
-                gestureCenter.setY(itemOriginPos.y());
-                hasItemCrossedBoundary = true;
-            }
-            //check if the lower boundry could be adjusted
-            if(itemOriginPos.y()+ mCurrentSize.height() <= mWindowSize.height()+5) {
-                //Image is before the right boundry leaving blank space
-                //stick the image to the right corner
-                gestureCenter.setY(itemOriginPos.y()+ mCurrentSize.height());
-                hasItemCrossedBoundary = true;
-            }
-            if((mCurrentSize.height() - mWindowSize.height() <= 20) && !hasItemCrossedBoundary) {
-                gestureCenter.setY(mWindowSize.height()/2 + (qAbs(itemOriginPos.y()) - 10));
-            }
-        }
+    
+    //special case for images that are smaller on both sides
+    //centering of the gesture is important to prevent movement of the image
+    //while zoom in or out
+    if( (mCurrentSize.height() <= mWindowSize.height()) && (mCurrentSize.width() <= mWindowSize.width()) ) {
+        gestureCenter.setX(mWindowSize.width()/2);
+        gestureCenter.setY(mWindowSize.height()/2);
     }
-    //control the zoom Factor to boundaries
-    if(mCurrentSize.width() > mWindowSize.width() && requiredSize.width() <= mWindowSize.width())
-    {
-        zoomFactor =  mWindowSize.width()/mCurrentSize.width();
-
-    }
-    else if(mCurrentSize.height() > mWindowSize.height() && requiredSize.height() <= mWindowSize.height())
-    {
-        zoomFactor =  mWindowSize.height()/mCurrentSize.height();
-
-    }
-
+        
     //reduce the ZF so as to show a decelerated effect at max/min levels
-
+/*
     if(mCurrentSize.width() > mMaxScaleDecSize.width() && zoomFactor > 1 ) {
         zoomFactor = 1.0 + ((zoomFactor-1.0)/6) ;
     }
         if(mCurrentSize.width() < mMinDecScaleSize.width() && zoomFactor < 1 ) {
         zoomFactor = 1.0 - ((1.0-zoomFactor)/6) ;
     }
-
+*/
 
 }
 
@@ -425,6 +416,7 @@
         mMaxScaleDecSize.scale(mWindowSize*7, Qt::KeepAspectRatio);
         mMinScaleSize = mItemSize* 0.7;
         mMinDecScaleSize = mItemSize;
+        mCurrentSize = mItemSize;
         mZoomItem->setPixmap(targetPixmap);
         finalizeWidgetTransform();
         }
@@ -542,7 +534,7 @@
     mBlackBackgroundItem->setZValue(mMaxZValue - 1);
     mBlackBackgroundItem->show();
     m_AnimRefPoint = animRefPoint;
-    QSizeF requiredSize = mItemSize;
+    QSizeF requiredSize = mMinDecScaleSize;
     //MAXDTZOOMIN size is set to 3.5 times window size
     requiredSize.scale(mWindowSize*MAXDTZOOMIN, Qt::KeepAspectRatio);
 	m_FinalAnimatedScaleFactor = requiredSize.width()/mMinDecScaleSize.width();
@@ -550,9 +542,11 @@
     mIncSF = 1;
     //preserve the size when zoom out was initiated, requried for calculates applicable/req scale factor
     //SF has to always greater than 1 for upscaling, hence range for zoomout is [1,m_FinalAnimatedScaleFactor]
-    msfInc = (m_FinalAnimatedScaleFactor-1)/NOOFSTEPS;
+    msfInc = (m_FinalAnimatedScaleFactor-1)/(NOOFSTEPSZI);
+    //preserve the size when zoom out was initiated, requried for calculates applicable/req scale factor
+    minitSize = mCurrentSize;
     //set the no. of steps for double tap animation 
-    mdoubletapSteps = NOOFSTEPS;
+    mdoubletapSteps = NOOFSTEPSZI;
     animateDoubleTap();
 
 }
@@ -564,12 +558,12 @@
     //initiale variable for double tap animation
     mIncSF = 1;
     //calculate the step increment SF for each step
-    msfInc = (1 - m_FinalAnimatedScaleFactor)/NOOFSTEPS;
+    msfInc = (1 - m_FinalAnimatedScaleFactor)/(NOOFSTEPSZO);
     //preserve the size when zoom out was initiated, requried for calculates applicable/req scale factor
-    mzoSize = mCurrentSize;
+    minitSize = mCurrentSize;
     //set the no. of steps for double tap animation 
     //AA:: the no.of steps are kept the same for zoomin/zoomout, however tweaking them can be considered
-    mdoubletapSteps = NOOFSTEPS;
+    mdoubletapSteps = NOOFSTEPSZO;
     animateDoubleTap();
     //AA
    
@@ -583,17 +577,17 @@
     if(m_FinalAnimatedScaleFactor > 1) {
         //AA::zoomin case
         mIncSF += msfInc;
-        qreal reqSF = (mItemSize.width()*(mIncSF))/mCurrentSize.width();
+        qreal reqSF = (minitSize.width()*(mIncSF))/mCurrentSize.width();
         zoomImage(reqSF, m_AnimRefPoint);
         }
     if(m_FinalAnimatedScaleFactor < 1) {
         //AA::zoomout case
         mIncSF -= msfInc;
-        qreal reqSF = (mzoSize.width()* mIncSF)/mCurrentSize.width();
+        qreal reqSF = (minitSize.width()* mIncSF)/mCurrentSize.width();
         zoomImage(reqSF, m_AnimRefPoint);
         }   
     //check if all steps are done,if not emit signal to continue the animation
-    if(mdoubletapSteps >= 1 ){
+    if(mdoubletapSteps > 1 ){
         mdoubletapSteps -= 1;
         emit stepZoom();    
         }
@@ -627,6 +621,9 @@
         killTimer(mTimerId);
         mTimerId = 0;
     }
+    else {
+        HbScrollArea::timerEvent( event );
+    }
 }
 
 bool GlxZoomWidget::isFocussedItemCorrupt()