ui/widgets/glxzoomwidget/src/glxzoomwidget.cpp
changeset 50 a0f57508af73
parent 45 863223ea6961
child 52 a3a4c0de738e
equal deleted inserted replaced
45:863223ea6961 50:a0f57508af73
    17 */
    17 */
    18 #include <QPinchGesture>
    18 #include <QPinchGesture>
    19 #include <hbiconitem.h>
    19 #include <hbiconitem.h>
    20 #include <QTimeLine>
    20 #include <QTimeLine>
    21 #include <QGesture>
    21 #include <QGesture>
       
    22 #include <hbinstance.h>
    22 #include "glximagedecoderwrapper.h"
    23 #include "glximagedecoderwrapper.h"
    23 #include "glxmodelparm.h"
    24 #include "glxmodelparm.h"
    24 #include "glxzoomwidget.h"
    25 #include "glxzoomwidget.h"
    25 
    26 
    26 GlxZoomWidget::GlxZoomWidget(QGraphicsItem *parent):HbScrollArea(parent), mModel(NULL), mMinZValue(MINZVALUE), mMaxZValue(MAXZVALUE), mImageDecodeRequestSend(false), mPinchGestureOngoing(false), mDecodedImageAvailable(false), mTimerId(0)
    27 GlxZoomWidget::GlxZoomWidget(QGraphicsItem *parent):HbScrollArea(parent), mModel(NULL), mMinZValue(MINZVALUE), mMaxZValue(MAXZVALUE), mImageDecodeRequestSend(false), mPinchGestureOngoing(false), mDecodedImageAvailable(false),mZoomOngoing(false), mTimerId(0)
    27 {
    28 {
    28     grabGesture(Qt::PinchGesture);
    29     grabGesture(Qt::PinchGesture);
    29     grabGesture(Qt::TapGesture);
    30     grabGesture(Qt::TapGesture);
    30     setAcceptTouchEvents(true) ;
    31     setAcceptTouchEvents(true) ;
    31     setFrictionEnabled(false);
    32     setFrictionEnabled(false);
    81 void GlxZoomWidget::setWindowSize(QSize windowSize)
    82 void GlxZoomWidget::setWindowSize(QSize windowSize)
    82 {
    83 {
    83     mWindowSize = windowSize;
    84     mWindowSize = windowSize;
    84     mBlackBackgroundItem->setGeometry(QRectF(QPointF(0,0), mWindowSize));
    85     mBlackBackgroundItem->setGeometry(QRectF(QPointF(0,0), mWindowSize));
    85     //try to reset the max and min zoomed size here
    86     //try to reset the max and min zoomed size here
       
    87     //In case the zoom widget is in background reset it
       
    88     if(!mZoomOngoing && mModel) {
       
    89         retreiveFocusedImage();
       
    90     }
       
    91     setZoomParams();
       
    92 }
       
    93 
       
    94 void GlxZoomWidget::forceZoomToBackground()
       
    95 {
       
    96     mBlackBackgroundItem->hide();
       
    97     //push the widget back to background
       
    98     setZValue(mMinZValue);
       
    99     mZoomOngoing = false;
       
   100     emit zoomWidgetMovedBackground(mFocusIndex);
       
   101     //this actually resets the ZoomWidget and decoder
       
   102     if(mImageDecoder) {
       
   103         mImageDecoder->resetDecoder();
       
   104     }
       
   105     retreiveFocusedImage();
       
   106 
    86 }
   107 }
    87 
   108 
    88 void GlxZoomWidget::indexChanged(int index)
   109 void GlxZoomWidget::indexChanged(int index)
    89 {
   110 {
    90     Q_UNUSED(index);
       
    91     if(mFocusIndex != index) {
   111     if(mFocusIndex != index) {
    92         mImageDecoder->resetDecoder();//reset the decoder first to cancel pending tasks
   112         mImageDecoder->resetDecoder();//reset the decoder first to cancel pending tasks
    93         mImageDecodeRequestSend = false;
   113         mImageDecodeRequestSend = false;
    94         mDecodedImageAvailable = false;
   114         mDecodedImageAvailable = false;
    95         retreiveFocusedImage();  //Update mZoomItem with focused Image
   115         retreiveFocusedImage();  //Update mZoomItem with focused Image
   160                     mTimerId = startTimer(500);
   180                     mTimerId = startTimer(500);
   161                 }
   181                 }
   162             else {
   182             else {
   163                 killTimer(mTimerId);
   183                 killTimer(mTimerId);
   164                 mTimerId = 0;
   184                 mTimerId = 0;
   165                 animateZoomOut(gesture->position());
   185                 animateZoomOut(hbInstance->allMainWindows().first()->mapToScene(gesture->position().toPoint()));
   166             }
   186             }
   167         }
   187         }
   168         event->accept(gesture);
   188         event->accept(gesture);
   169         return true;
   189         return true;
   170     }
   190     }
   171      if (QGesture *pinch = event->gesture(Qt::PinchGesture))  {
   191      if (QGesture *pinch = event->gesture(Qt::PinchGesture))  {
   172        QPinchGesture* pinchG = static_cast<QPinchGesture *>(pinch);
   192        QPinchGesture* pinchG = static_cast<QPinchGesture *>(pinch);
   173        QPinchGesture::ChangeFlags changeFlags = pinchG->changeFlags();
   193        QPinchGesture::ChangeFlags changeFlags = pinchG->changeFlags();
   174        if (changeFlags & QPinchGesture::ScaleFactorChanged) {
   194        if (changeFlags & QPinchGesture::ScaleFactorChanged) {
   175             mPinchGestureOngoing = true;
   195             mPinchGestureOngoing = true;
       
   196             mZoomOngoing = true;
   176             //bring the zoom widget to foreground
   197             //bring the zoom widget to foreground
   177             setZValue(mMaxZValue);
   198             setZValue(mMaxZValue);
   178             //show the black background
   199             //show the black background
   179             mBlackBackgroundItem->setParentItem(parentItem());
   200             mBlackBackgroundItem->setParentItem(parentItem());
   180             mBlackBackgroundItem->setZValue(mMaxZValue - 1);
   201             mBlackBackgroundItem->setZValue(mMaxZValue - 1);
   182 
   203 
   183             //retreive the gesture values
   204             //retreive the gesture values
   184             qreal value = pinchG->scaleFactor() / pinchG->lastScaleFactor();
   205             qreal value = pinchG->scaleFactor() / pinchG->lastScaleFactor();
   185             QPointF center = pinchG->property("centerPoint").toPointF();
   206             QPointF center = pinchG->property("centerPoint").toPointF();
   186             //set the gesture center to the scene coordinates
   207             //set the gesture center to the scene coordinates
   187             QPointF sceneGestureCenter = source->sceneTransform().map(center);
   208             QPointF sceneGestureCenter = hbInstance->allMainWindows().first()->mapToScene(center.toPoint());
   188             zoomImage(value, sceneGestureCenter);
   209             zoomImage(value, sceneGestureCenter);
   189 
   210 
   190         }
   211         }
   191        if (pinchG->state() == Qt::GestureStarted) {
   212        if (pinchG->state() == Qt::GestureStarted) {
   192            emit pinchGestureReceived(mFocusIndex);
   213            emit pinchGestureReceived(mFocusIndex);
   209 //push the Zoom widget to background when zoomed image size nears FS image
   230 //push the Zoom widget to background when zoomed image size nears FS image
   210            if(mStepCurrentSize.width() <= mMinDecScaleSize.width()*1.3)  {
   231            if(mStepCurrentSize.width() <= mMinDecScaleSize.width()*1.3)  {
   211                mBlackBackgroundItem->hide();
   232                mBlackBackgroundItem->hide();
   212                //push the widget back to background
   233                //push the widget back to background
   213                setZValue(mMinZValue);
   234                setZValue(mMinZValue);
       
   235                mZoomOngoing = false;
   214                emit zoomWidgetMovedBackground(mFocusIndex);
   236                emit zoomWidgetMovedBackground(mFocusIndex);
   215                //do not reset the transform here as it will then zoom-in the widget to decoded image size
   237                //do not reset the transform here as it will then zoom-in the widget to decoded image size
   216            }
   238            }
   217        }
   239        }
   218        //gesture accepted
   240        //gesture accepted
   226 
   248 
   227 }
   249 }
   228 
   250 
   229 void GlxZoomWidget::zoomImage(qreal zoomFactor, QPointF center)
   251 void GlxZoomWidget::zoomImage(qreal zoomFactor, QPointF center)
   230 {
   252 {
       
   253         // Pinch event filtering for very small zoom factors
       
   254     if (qAbs(1.0 - zoomFactor) < 0.007) {
       
   255         return;
       
   256     }
   231     adjustGestureCenter(center, zoomFactor);
   257     adjustGestureCenter(center, zoomFactor);
   232     QSizeF requiredSize(mCurrentSize.width()*zoomFactor, mCurrentSize.height()*zoomFactor);
   258     QSizeF requiredSize(mCurrentSize.width()*zoomFactor, mCurrentSize.height()*zoomFactor);
   233     limitRequiredSize(requiredSize);
   259     limitRequiredSize(requiredSize);
   234     if(requiredSize != mCurrentSize) {
   260     if(requiredSize != mCurrentSize) {
   235         QTransform zoomTransform = mZoomWidget->transform();
   261         QTransform zoomTransform = mZoomWidget->transform();
   277     {
   303     {
   278         gestureCenter.setY(mWindowSize.height()/2);
   304         gestureCenter.setY(mWindowSize.height()/2);
   279 
   305 
   280     }
   306     }
   281     //maintains the boundary of the edges for zoom out conditions
   307     //maintains the boundary of the edges for zoom out conditions
   282     if(zoomFactor < 1)
   308     if(zoomFactor < 1) {
   283     {
       
   284         QPointF itemOriginPos = mZoomWidget->sceneTransform().map(QPointF(0,0));
   309         QPointF itemOriginPos = mZoomWidget->sceneTransform().map(QPointF(0,0));
   285         bool hasWidthExceededWindow = mCurrentSize.width() > mWindowSize.width();
   310         bool hasWidthExceededWindow = mCurrentSize.width() > mWindowSize.width();
   286         bool hasHeightExceededWindow = mCurrentSize.height() > mWindowSize.height();
   311         bool hasHeightExceededWindow = mCurrentSize.height() > mWindowSize.height();
   287         if(itemOriginPos.x() >= 0)  {
   312         if(hasWidthExceededWindow) {
   288         //image has crossed left boundry leaving blank space
   313             bool hasItemCrossedBoundary = false;
   289             if(hasWidthExceededWindow) {
   314             if(itemOriginPos.x() >= -5)  {
       
   315                 //image has crossed left boundry leaving blank space
   290                 //stick the gesture to the left corner
   316                 //stick the gesture to the left corner
   291                 gestureCenter.setX(itemOriginPos.x());
   317                 gestureCenter.setX(itemOriginPos.x());
       
   318                 hasItemCrossedBoundary = true;
       
   319             }
       
   320         
       
   321             //Check if the right boundry can be adjusted
       
   322             if(itemOriginPos.x()+ mCurrentSize.width() <= mWindowSize.width()+5) {
       
   323                 //Image is before the right boundry leaving blank space
       
   324                 gestureCenter.setX(itemOriginPos.x()+ mCurrentSize.width() );
       
   325                 hasItemCrossedBoundary = true;
       
   326             }
       
   327             if((mCurrentSize.width() - mWindowSize.width() <= 20) && !hasItemCrossedBoundary) {
       
   328                 gestureCenter.setX(mWindowSize.width()/2 + (qAbs(itemOriginPos.x()) - 10));
   292             }
   329             }
   293         }
   330         }
   294         //Check if the right boundry can be adjusted
   331 
   295         if(itemOriginPos.x()+ mCurrentSize.width() <= mWindowSize.width()) {
   332         if(hasHeightExceededWindow) {
       
   333              bool hasItemCrossedBoundary = false;
       
   334             //check if the upper boundry could be adjusted
       
   335             if(itemOriginPos.y() >= -5) {
       
   336                 //image has crossed the upper boundry leaving blank space
       
   337                 //stick the image to the upper boundry
       
   338                 gestureCenter.setY(itemOriginPos.y());
       
   339                 hasItemCrossedBoundary = true;
       
   340             }
       
   341             //check if the lower boundry could be adjusted
       
   342             if(itemOriginPos.y()+ mCurrentSize.height() <= mWindowSize.height()+5) {
   296                 //Image is before the right boundry leaving blank space
   343                 //Image is before the right boundry leaving blank space
   297                 if(hasWidthExceededWindow) {
       
   298                     //stick the gesture to the right corner
       
   299                     gestureCenter.setX(itemOriginPos.x()+ mCurrentSize.width());
       
   300                 }
       
   301         }
       
   302         //check if the upper boundry could be adjusted
       
   303         if(itemOriginPos.y() >= 0) {
       
   304                 //image has crossed the upper boundry leaving blank space
       
   305                 if(hasHeightExceededWindow) {
       
   306                     //stick the image to the upper boundry
       
   307                     gestureCenter.setY(itemOriginPos.y());
       
   308                 }
       
   309         }
       
   310         //check if the lower boundry could be adjusted
       
   311         if(itemOriginPos.y()+ mCurrentSize.height() <= mWindowSize.height()) {
       
   312         //Image is before the right boundry leaving blank space
       
   313             if(hasHeightExceededWindow) {
       
   314                 //stick the image to the right corner
   344                 //stick the image to the right corner
   315                 gestureCenter.setY(itemOriginPos.y()+ mCurrentSize.height());
   345                 gestureCenter.setY(itemOriginPos.y()+ mCurrentSize.height());
   316             }
   346                 hasItemCrossedBoundary = true;
   317 
   347             }
       
   348             if((mCurrentSize.height() - mWindowSize.height() <= 20) && !hasItemCrossedBoundary) {
       
   349                 gestureCenter.setY(mWindowSize.height()/2 + (qAbs(itemOriginPos.y()) - 10));
       
   350             }
   318         }
   351         }
   319     }
   352     }
   320     //control the zoom Factor to boundaries
   353     //control the zoom Factor to boundaries
   321     if(mCurrentSize.width() > mWindowSize.width() && requiredSize.width() <= mWindowSize.width())
   354     if(mCurrentSize.width() > mWindowSize.width() && requiredSize.width() <= mWindowSize.width())
   322     {
   355     {
   458     }
   491     }
   459     return targetPixmap;
   492     return targetPixmap;
   460 
   493 
   461 }
   494 }
   462 
   495 
   463 
   496 void GlxZoomWidget::setZoomParams()
       
   497 {
       
   498     if (mModel)  {
       
   499         QVariant sizeVariant = mModel->data(mModel->index(mFocusIndex,0),GlxDimensionsRole);
       
   500         QSize fsSize;
       
   501         if(sizeVariant.isValid() &&  sizeVariant.canConvert<QSize> ()) {
       
   502             fsSize = sizeVariant.toSize();
       
   503             if(!(fsSize.width() < mWindowSize.width() && fsSize.height() < mWindowSize.height()))  {
       
   504                 fsSize.scale( mWindowSize, Qt::KeepAspectRatio);
       
   505             }
       
   506             mMaxScaleSize = fsSize;
       
   507             mMaxScaleSize.scale(mWindowSize*13, Qt::KeepAspectRatio);
       
   508             mMaxScaleDecSize = fsSize;
       
   509             mMaxScaleDecSize.scale(mWindowSize*7, Qt::KeepAspectRatio);
       
   510             mMinScaleSize = fsSize* 0.7;
       
   511             mMinDecScaleSize = fsSize;
       
   512         }
       
   513     }
       
   514 
       
   515 
       
   516 }
   464 
   517 
   465 
   518 
   466 
   519 
   467 void GlxZoomWidget::animateZoomIn(QPointF animRefPoint)
   520 void GlxZoomWidget::animateZoomIn(QPointF animRefPoint)
   468 {
   521 {
   469       emit pinchGestureReceived(mFocusIndex);
   522       emit pinchGestureReceived(mFocusIndex);
   470             //bring the zoom widget to foreground
   523             //bring the zoom widget to foreground
       
   524             mZoomOngoing = true;
   471             setZValue(mMaxZValue);
   525             setZValue(mMaxZValue);
   472             //show the black background
   526             //show the black background
   473             mBlackBackgroundItem->setParentItem(parentItem());
   527             mBlackBackgroundItem->setParentItem(parentItem());
   474             mBlackBackgroundItem->setZValue(mMaxZValue - 1);
   528             mBlackBackgroundItem->setZValue(mMaxZValue - 1);
   475             mBlackBackgroundItem->show();
   529             mBlackBackgroundItem->show();
   508 //push the Zoom widget to background when zoomed image size nears FS image
   562 //push the Zoom widget to background when zoomed image size nears FS image
   509            if(mStepCurrentSize.width() <= mMinDecScaleSize.width()*1.3)  {
   563            if(mStepCurrentSize.width() <= mMinDecScaleSize.width()*1.3)  {
   510                mBlackBackgroundItem->hide();
   564                mBlackBackgroundItem->hide();
   511                //push the widget back to background
   565                //push the widget back to background
   512                setZValue(mMinZValue);
   566                setZValue(mMinZValue);
       
   567                mZoomOngoing = false;
   513                emit zoomWidgetMovedBackground(mFocusIndex);
   568                emit zoomWidgetMovedBackground(mFocusIndex);
   514                //do not reset the transform here as it will then zoom-in the widget to decoded image size
   569                //do not reset the transform here as it will then zoom-in the widget to decoded image size
   515            }
   570            }
   516 }
   571 }
   517 
   572