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 } |
|