source: trunk/examples/gestures/imagegestures/imagewidget.cpp@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "imagewidget.h"
42
43#include <QtGui>
44
45//! [constructor]
46ImageWidget::ImageWidget(QWidget *parent)
47 : QWidget(parent),
48 position(0),
49 horizontalOffset(0),
50 verticalOffset(0),
51 rotationAngle(0),
52 scaleFactor(1),
53 currentStepScaleFactor(1)
54
55{
56 setMinimumSize(QSize(100,100));
57
58//! [enable gestures]
59 grabGesture(Qt::PanGesture);
60 grabGesture(Qt::PinchGesture);
61 grabGesture(Qt::SwipeGesture);
62//! [enable gestures]
63}
64//! [constructor]
65
66//! [event handler]
67bool ImageWidget::event(QEvent *event)
68{
69 if (event->type() == QEvent::Gesture)
70 return gestureEvent(static_cast<QGestureEvent*>(event));
71 return QWidget::event(event);
72}
73//! [event handler]
74
75void ImageWidget::paintEvent(QPaintEvent*)
76{
77 QPainter p(this);
78
79 float iw = currentImage.width();
80 float ih = currentImage.height();
81 float wh = height();
82 float ww = width();
83
84 p.translate(ww/2, wh/2);
85 p.translate(horizontalOffset, verticalOffset);
86 p.rotate(rotationAngle);
87 p.scale(currentStepScaleFactor * scaleFactor, currentStepScaleFactor * scaleFactor);
88 p.translate(-iw/2, -ih/2);
89 p.drawImage(0, 0, currentImage);
90}
91
92void ImageWidget::mouseDoubleClickEvent(QMouseEvent *)
93{
94 rotationAngle = 0;
95 scaleFactor = 1;
96 currentStepScaleFactor = 1;
97 verticalOffset = 0;
98 horizontalOffset = 0;
99 update();
100}
101
102//! [gesture event handler]
103bool ImageWidget::gestureEvent(QGestureEvent *event)
104{
105 if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
106 swipeTriggered(static_cast<QSwipeGesture *>(swipe));
107 else if (QGesture *pan = event->gesture(Qt::PanGesture))
108 panTriggered(static_cast<QPanGesture *>(pan));
109 if (QGesture *pinch = event->gesture(Qt::PinchGesture))
110 pinchTriggered(static_cast<QPinchGesture *>(pinch));
111 return true;
112}
113//! [gesture event handler]
114
115void ImageWidget::panTriggered(QPanGesture *gesture)
116{
117#ifndef QT_NO_CURSOR
118 switch (gesture->state()) {
119 case Qt::GestureStarted:
120 case Qt::GestureUpdated:
121 setCursor(Qt::SizeAllCursor);
122 break;
123 default:
124 setCursor(Qt::ArrowCursor);
125 }
126#endif
127 QPointF delta = gesture->delta();
128 horizontalOffset += delta.x();
129 verticalOffset += delta.y();
130 update();
131}
132
133void ImageWidget::pinchTriggered(QPinchGesture *gesture)
134{
135 QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
136 if (changeFlags & QPinchGesture::RotationAngleChanged) {
137 qreal value = gesture->property("rotationAngle").toReal();
138 qreal lastValue = gesture->property("lastRotationAngle").toReal();
139 rotationAngle += value - lastValue;
140 }
141 if (changeFlags & QPinchGesture::ScaleFactorChanged) {
142 qreal value = gesture->property("scaleFactor").toReal();
143 currentStepScaleFactor = value;
144 }
145 if (gesture->state() == Qt::GestureFinished) {
146 scaleFactor *= currentStepScaleFactor;
147 currentStepScaleFactor = 1;
148 }
149 update();
150}
151
152//! [swipe function]
153void ImageWidget::swipeTriggered(QSwipeGesture *gesture)
154{
155 if (gesture->state() == Qt::GestureFinished) {
156 if (gesture->horizontalDirection() == QSwipeGesture::Left
157 || gesture->verticalDirection() == QSwipeGesture::Up)
158 goPrevImage();
159 else
160 goNextImage();
161 update();
162 }
163}
164//! [swipe function]
165
166void ImageWidget::resizeEvent(QResizeEvent*)
167{
168 update();
169}
170
171void ImageWidget::openDirectory(const QString &path)
172{
173 this->path = path;
174 QDir dir(path);
175 QStringList nameFilters;
176 nameFilters << "*.jpg" << "*.png";
177 files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);
178
179 position = 0;
180 goToImage(0);
181 update();
182}
183
184QImage ImageWidget::loadImage(const QString &fileName)
185{
186 QImageReader reader(fileName);
187 if (!reader.canRead()) {
188 qDebug() << fileName << ": can't load image";
189 return QImage();
190 }
191
192 QImage image;
193 if (!reader.read(&image)) {
194 qDebug() << fileName << ": corrupted image";
195 return QImage();
196 }
197 return image;
198}
199
200void ImageWidget::goNextImage()
201{
202 if (files.isEmpty())
203 return;
204
205 if (position < files.size()-1) {
206 ++position;
207 prevImage = currentImage;
208 currentImage = nextImage;
209 if (position+1 < files.size())
210 nextImage = loadImage(path+QLatin1String("/")+files.at(position+1));
211 else
212 nextImage = QImage();
213 }
214 update();
215}
216
217void ImageWidget::goPrevImage()
218{
219 if (files.isEmpty())
220 return;
221
222 if (position > 0) {
223 --position;
224 nextImage = currentImage;
225 currentImage = prevImage;
226 if (position > 0)
227 prevImage = loadImage(path+QLatin1String("/")+files.at(position-1));
228 else
229 prevImage = QImage();
230 }
231 update();
232}
233
234void ImageWidget::goToImage(int index)
235{
236 if (files.isEmpty())
237 return;
238
239 if (index < 0 || index >= files.size()) {
240 qDebug() << "goToImage: invalid index: " << index;
241 return;
242 }
243
244 if (index == position+1) {
245 goNextImage();
246 return;
247 }
248
249 if (position > 0 && index == position-1) {
250 goPrevImage();
251 return;
252 }
253
254 position = index;
255
256 if (index > 0)
257 prevImage = loadImage(path+QLatin1String("/")+files.at(position-1));
258 else
259 prevImage = QImage();
260 currentImage = loadImage(path+QLatin1String("/")+files.at(position));
261 if (position+1 < files.size())
262 nextImage = loadImage(path+QLatin1String("/")+files.at(position+1));
263 else
264 nextImage = QImage();
265 update();
266}
Note: See TracBrowser for help on using the repository browser.