ui/views/fullscreenview/src/glxzoomcontrol.cpp
changeset 42 5e1df1b52eb3
parent 41 ae07d189b490
child 43 72396548277c
equal deleted inserted replaced
41:ae07d189b490 42:5e1df1b52eb3
     1 /*
       
     2 * Copyright (c) 2009 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 "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:   ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 #include "glxzoomcontrol.h"
       
    19 #include "glximagedecoderwrapper.h"
       
    20 #include "glxmodelparm.h"
       
    21 #include <hbicon.h>
       
    22 #include <glxmediamodel.h>
       
    23 #include <QtDebug>
       
    24 #include <hbinstance.h>
       
    25 #include <hbiconitem.h>
       
    26 #include <QDebug>
       
    27 
       
    28 GlxZoomControl::GlxZoomControl(QGraphicsItem *parent) : HbScrollArea(parent),mIsControlActivated(false), mIsItemChanged(true)
       
    29 {
       
    30 	setScrollDirections(Qt::Horizontal | Qt::Vertical);
       
    31 	hide();
       
    32 	setZValue(6);
       
    33 	setScrollingStyle(PanOrFlick);
       
    34 	mBlackBackgroundItem = new HbIconItem(parent);
       
    35 	mBlackBackgroundItem->setBrush(QBrush(Qt::black));
       
    36 	mBlackBackgroundItem->hide();
       
    37 	mZoomWidget = new QGraphicsWidget(this);
       
    38 	mZoomItem = new QGraphicsPixmapItem(mZoomWidget);
       
    39 	mImageDecoder = new GlxImageDecoderWrapper;	
       
    40 
       
    41 }
       
    42 
       
    43 GlxZoomControl::~GlxZoomControl()
       
    44 {
       
    45 	resetZoomControl();
       
    46 	delete mZoomItem;
       
    47 	delete mZoomWidget;
       
    48 	mImageDecoder->resetDecoder();
       
    49 	delete mImageDecoder;
       
    50 	delete mBlackBackgroundItem;
       
    51 
       
    52 }
       
    53 
       
    54 void GlxZoomControl::zoomImage(int zoomFactor)
       
    55 {
       
    56 	qDebug("@@@GlxZoomControl::zoomImage  ZF=%d, InitialZf=%d", zoomFactor, mInitialZoomFactor);
       
    57 	if(mIsItemChanged)	{
       
    58 		initializeZoomControl(zoomFactor);
       
    59 	}
       
    60 	if(zoomFactor > mInitialZoomFactor) {
       
    61 
       
    62 		qreal zoomPercent = qreal(zoomFactor)/100.00;
       
    63 		QSizeF requiredSize = QSize(qreal(mItemSize.width() * zoomPercent), qreal(mItemSize.height() * zoomPercent ));
       
    64 		calculatePanOffset();
       
    65 		mZoomWidget->scale(requiredSize.width()/mCurrentSize.width(), requiredSize.height()/mCurrentSize.height());
       
    66 		qDebug()<<"GlxZoomControl::zoomImage scaling factor"<<requiredSize.width()/mCurrentSize.width()<<requiredSize.height()/mCurrentSize.height();
       
    67 		qDebug()<<"GlxZoomControl::zoomImage required Size"<<requiredSize.width()<<requiredSize.height();
       
    68 		qDebug()<<"GlxZoomControl::zoomImage current Size"<<mCurrentSize.width()<<mCurrentSize.height();
       
    69 		qDebug()<<"GlxZoomControl::zoomImage item Size"<<mItemSize.width()<<mItemSize.height();
       
    70 
       
    71 		//mZoomWidget->setGeometry(QRectF(-0.5*QPointF(requiredSize.width(),requiredSize.height()),requiredSize ));
       
    72 		//mZoomWidget->setPos(mWindowSize.width()/2 - requiredSize.width()/2,mWindowSize.height()/2 - requiredSize.height()/2);
       
    73 		mCurrentSize = requiredSize;	
       
    74 		mCurrentZoomFactor = zoomFactor;
       
    75 		updateItemPosition();
       
    76 		if(!mIsControlActivated) {
       
    77 			show();
       
    78 			mBlackBackgroundItem->show();
       
    79 			mIsControlActivated = true;
       
    80 			emit hideFullScreenUi();
       
    81 		}
       
    82 	}
       
    83 	if(zoomFactor < mInitialZoomFactor)
       
    84 	{
       
    85 		mBlackBackgroundItem->hide();
       
    86 		hide();
       
    87 		mPanOffset.setX(0);
       
    88 		mPanOffset.setY(0);
       
    89 		updateItemPosition();
       
    90 		mIsControlActivated = false;
       
    91 		//mZoomWidget->resetTransform();
       
    92 	}
       
    93 }
       
    94 
       
    95 void GlxZoomControl::initializeZoomControl(int zoomFactor)
       
    96 {
       
    97 	 qDebug("@@@GlxZoomControl::initializeZoomControl Zoom Factor %d", zoomFactor);
       
    98 	 if(mIsControlActivated || zoomFactor < mInitialZoomFactor)
       
    99 	 {
       
   100 		return;
       
   101 	 }
       
   102 	 qDebug("@@@GlxZoomControl::initializeZoomControl Context not activated yet");
       
   103 	 //get the image path and request for a decoded pixmap first
       
   104 	 QString imagePath = (mModel->data(mModel->index(mModel->data(mModel->index(0,0),GlxFocusIndexRole).value<int>(),0),GlxUriRole)).value<QString>();
       
   105 	 mImageDecoder->decodeImage(imagePath);
       
   106 	 connect(mImageDecoder, SIGNAL(pixmapDecoded()), this, SLOT(decodedImageAvailable()));
       
   107 	 QVariant variant = mModel->data(mModel->index(mModel->data(mModel->index(0,0),GlxFocusIndexRole).value<int>(),0),GlxFsImageRole);
       
   108 	 if ( variant.isValid() &&  variant.canConvert<HbIcon> () ) {
       
   109 		 qDebug("@@@GlxZoomControl::initializeZoomControl valid icon");
       
   110 		 QIcon itemIcon = variant.value<HbIcon>().qicon();
       
   111 		 //QSize windowSize(360,640);
       
   112 		 QSize itemSize = itemIcon.actualSize(mWindowSize);
       
   113 		 QPixmap itemPixmap = itemIcon.pixmap(itemSize);
       
   114 		 //if(itemPixmap.isNull())
       
   115 		 qDebug("@@@GlxZoomControl::initializeZoomControl Null Pixmap");
       
   116 		 //set item size to the actual size
       
   117 		 mItemSize = (mModel->data(mModel->index(mModel->data(mModel->index(0,0),GlxFocusIndexRole).value<int>(),0),GlxDimensionsRole)).value<QSize>();
       
   118 		 mCurrentSize = itemPixmap.size();
       
   119 		 mZoomItem->setPixmap(itemPixmap);
       
   120 		 mZoomWidget->setGeometry(QRectF(-0.5*QPointF(mCurrentSize.width(),mCurrentSize.height()),mItemSize ));
       
   121 		 mZoomWidget->setPos(mWindowSize.width()/2 - mCurrentSize.width()/2,mWindowSize.height()/2 - mCurrentSize.height()/2);
       
   122 		 //show();
       
   123          //mIsControlActivated = true;
       
   124 		 mIsItemChanged = false;
       
   125 		 setContentWidget(mZoomWidget);
       
   126 	 }
       
   127 }
       
   128 
       
   129 void GlxZoomControl::setModel(QAbstractItemModel *model)
       
   130 {
       
   131 	GlxMediaModel *glxModel = dynamic_cast<GlxMediaModel *>(model);
       
   132     if ( glxModel ==NULL ||  glxModel == mModel) {
       
   133         return ;
       
   134     }
       
   135 	mModel = glxModel;
       
   136 }
       
   137 
       
   138 void GlxZoomControl::resetZoomControl()
       
   139 {
       
   140 	qDebug("@@@GlxZoomControl::resetZoomControl");
       
   141 	mBlackBackgroundItem->hide();
       
   142 	hide();
       
   143 	mZoomWidget->resetTransform();
       
   144 	mZoomItem->setPixmap(QPixmap());
       
   145 	mItemSize = QSizeF(0,0);
       
   146 	mCurrentSize = mItemSize;
       
   147 	mIsControlActivated = false;
       
   148 	mIsItemChanged = true;
       
   149 	mInitialZoomFactor = 0;
       
   150 	mPanOffset.setX(0);
       
   151 	mPanOffset.	setY(0);
       
   152 	mImageDecoder->resetDecoder();		
       
   153 }
       
   154 
       
   155 void GlxZoomControl::indexChanged(int index)
       
   156 {
       
   157 	Q_UNUSED(index);
       
   158 	qDebug("@@@GlxZoomControl::indexChanged");
       
   159 	resetZoomControl();
       
   160 
       
   161 }
       
   162 
       
   163 void GlxZoomControl::decodedImageAvailable()
       
   164 {
       
   165 	//new bitmap with better resolution is available
       
   166 	//so set it to the item
       
   167 	QPixmap decodedPixmap = mImageDecoder->getPixmap();
       
   168 	if(decodedPixmap.isNull()){
       
   169 		return;
       
   170 	}
       
   171 	mCurrentSize = decodedPixmap.size();
       
   172 	//this is important if not done then old transforms will be applied on the new image
       
   173 	mZoomWidget->resetTransform();
       
   174 	mZoomItem->setPixmap(decodedPixmap);
       
   175 	QPointF undefferedPos;
       
   176 	undefferedPos.setX(mWindowSize.width()/2 - mCurrentSize.width()/2);
       
   177 	undefferedPos.setY(mWindowSize.height()/2 - mCurrentSize.height()/2);
       
   178 	mZoomWidget->setGeometry(QRectF(undefferedPos,mCurrentSize )); //temporarily setting it to an undeffered position
       
   179 	//update the image transforms
       
   180 	zoomImage(mCurrentZoomFactor);
       
   181 }
       
   182 
       
   183 void GlxZoomControl::initialZoomFactor(int initZoomFactor)
       
   184 {
       
   185 	qDebug("@@@GlxZoomControl::initialZoomFactor initZoomFactor=%d", initZoomFactor );
       
   186 	resetZoomControl();
       
   187 	mInitialZoomFactor = initZoomFactor;
       
   188 }
       
   189 
       
   190 void GlxZoomControl::setWindowSize (QSize windowSize)
       
   191 {
       
   192 	if(mWindowSize != windowSize) {
       
   193 		mWindowSize = windowSize;
       
   194 		mBlackBackgroundItem->setSize(mWindowSize);
       
   195 		mBlackBackgroundItem->setPos(0,0);
       
   196 		if(!mIsItemChanged) {
       
   197 			//first calculate offset because after orientation change this value will be lost
       
   198 			calculatePanOffset();
       
   199 			//update the item position WRT the new window size
       
   200 			updateItemPosition();
       
   201 
       
   202 		}
       
   203 	}
       
   204 }
       
   205 void GlxZoomControl::updateItemPosition()
       
   206 {
       
   207 	qreal zoomPercent = qreal(mCurrentZoomFactor)/100.00;
       
   208 	QPointF undefferedPos;
       
   209 	//calculate position if no panning was done
       
   210 	undefferedPos.setX(mWindowSize.width()/2 - mCurrentSize.width()/2);
       
   211 	undefferedPos.setY(mWindowSize.height()/2 - mCurrentSize.height()/2);
       
   212 	QPointF offset = mPanOffset;
       
   213 	//convert offset value WRT current zoomFactor
       
   214 	offset *= zoomPercent;
       
   215 	QPointF finalPos = undefferedPos + offset;
       
   216 	//check for boundry conditions 
       
   217 	checkandAdjustImageBoundaries(finalPos, undefferedPos);
       
   218 	qDebug()<<"GlxZoomControl::updateItemPosition offset x%d, y%d "<<offset.x()<< offset.y();
       
   219 	//mZoomWidget->setPos(undefferedPos + offset);
       
   220 	mZoomWidget->setGeometry(QRectF(finalPos,mCurrentSize ));
       
   221 }
       
   222 
       
   223 void GlxZoomControl::calculatePanOffset()
       
   224 {
       
   225 	qreal zoomPercent = qreal(mCurrentZoomFactor)/100.00;
       
   226 	QPointF currentPos = mZoomWidget->pos();
       
   227 	//calculate position if no panning was done
       
   228 	QPointF undefferedPos;
       
   229 	undefferedPos.setX(mWindowSize.width()/2 - mCurrentSize.width()/2);
       
   230 	undefferedPos.setY(mWindowSize.height()/2 - mCurrentSize.height()/2);
       
   231 	//get the offset with the current zoomFactor which is the difference between currentPos and undefferedPos
       
   232 	QPointF offset = currentPos - undefferedPos ;
       
   233 	qDebug()<<"GlxZoomControl::calculatePanOffset current Pos x%d, y%d undeffered x %d, y %d"<<currentPos.x()<< currentPos.y()<< undefferedPos.x()<< undefferedPos.y();
       
   234     mPanOffset = offset;
       
   235 	//convert the offset value WRT a 100% zoomed image as that will be used for reference 
       
   236 	mPanOffset /= zoomPercent;
       
   237 	qDebug()<<"GlxZoomControl::calculatePanOffset mPanOffset x%d, y%d "<<mPanOffset.x()<< mPanOffset.y();
       
   238 }
       
   239 
       
   240 void GlxZoomControl::checkandAdjustImageBoundaries(QPointF &finalPos, QPointF undefferedPos)
       
   241 {
       
   242 	//check for boundary conditions in X Axis
       
   243 
       
   244 	//for Left side
       
   245 	//since the image is positioned WRT to screens top left corner(0,0) so if the images top left corner's X (finalPos.x()) is positive
       
   246 	//then boundry conditions for image to be on the leftmost side is met
       
   247 	if(finalPos.x() > 0) {
       
   248 		//chk if the original image position without any offset has also reached boundry conditions
       
   249 		if(undefferedPos.x() < 0) {
       
   250 		//set the image to the leftmost axis on the screen
       
   251 		finalPos.setX(0);
       
   252 		}
       
   253 		//if original image position without any offset has also reached boundry conditions then use the undefferedPos 
       
   254 		else {
       
   255 			finalPos.setX(undefferedPos.x());
       
   256 			//set offset to 0 as it is of no use anymore
       
   257 			mPanOffset.setX(0);
       
   258 		}
       
   259 	}
       
   260 
       
   261 	//Right side
       
   262 	//since the image is positioned WRT to screens top left corner(0,0) so if image Position added to the image dimensions is 
       
   263 	//greater than the screen dimensions then boundfy conditions for rightmost and lowest points are met.
       
   264 	//for X axis width will be of our concern
       
   265 	if((finalPos.x() + mCurrentSize.width()) <  mWindowSize.width()){
       
   266 		//if original image position without any offset has also reached boundry conditions then use the undefferedPos 
       
   267 		if ((undefferedPos.x() + mCurrentSize.width()) <  mWindowSize.width()) 	{
       
   268 			finalPos.setX(undefferedPos.x());
       
   269 			//set offset to 0 as it is of no use anymore
       
   270 			mPanOffset.setX(0);			
       
   271 		}
       
   272 		else {
       
   273 			//set the image to the rightmost axis on the screen
       
   274 			finalPos.setX(mWindowSize.width()- mCurrentSize.width());
       
   275 		}
       
   276 	}
       
   277 
       
   278 
       
   279 	//check for boundary conditions in Y Axis
       
   280 
       
   281 	//top
       
   282 	//since the image is positioned WRT to screens top left corner(0,0) so if the images top left corner's Y (finalPos.y()) is positive
       
   283 	//then boundry conditions for image to be on the topmost side is met
       
   284 	if(finalPos.y() > 0) {
       
   285 		//chk if the original image position without any offset has also reached boundry conditions
       
   286 		if(undefferedPos.y() < 0) {
       
   287 		//set the image to the topmost axis on the screen
       
   288 		finalPos.setY(0);
       
   289 		}
       
   290 		//if original image position without any offset has also reached boundry conditions then use the undefferedPos 
       
   291 		else {
       
   292 			finalPos.setY(undefferedPos.y());
       
   293 			//set offset to 0 as it is of no use anymore
       
   294 			mPanOffset.setY(0);
       
   295 		}
       
   296 	}
       
   297 
       
   298 	//bottom
       
   299 	//since the image is positioned WRT to screens top left corner(0,0) so if image Position added to the image dimensions is 
       
   300 	//greater than the screen dimensions then boundfy conditions for rightmost and lowest points are met.
       
   301 	//for Y axis height will be of our concern
       
   302 
       
   303 	if((finalPos.y() + mCurrentSize.height()) <  mWindowSize.height()){
       
   304 		//if original image position without any offset has also reached boundry conditions then use the undefferedPos 
       
   305 		if ((undefferedPos.y() + mCurrentSize.height()) <  mWindowSize.height()) 	{
       
   306 			finalPos.setY(undefferedPos.y());
       
   307 			//set offset to 0 as it is of no use anymore
       
   308 			mPanOffset.setY(0);			
       
   309 		}
       
   310 		else {
       
   311 			//set the image to the lowest axis on the screen
       
   312 			finalPos.setY(mWindowSize.height()- mCurrentSize.height());
       
   313 		}
       
   314 	}
       
   315 
       
   316 }