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 |