1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the demonstration applications of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include "menumanager.h"
47 QHash
<QString
, SharedImage
*> DemoItem::sharedImageHash
;
48 QMatrix
DemoItem::matrix
;
50 DemoItem::DemoItem(QGraphicsScene
*scene
, QGraphicsItem
*parent
) : QGraphicsItem(parent
, scene
)
54 this->prepared
= false;
55 this->neverVisible
= false;
56 this->noSubPixeling
= false;
57 this->currentAnimation
= 0;
60 this->sharedImage
= new SharedImage();
61 ++this->sharedImage
->refCount
;
66 if(--this->sharedImage
->refCount
== 0){
67 if (!this->hashKey
.isEmpty())
68 DemoItem::sharedImageHash
.remove(this->hashKey
);
69 delete this->sharedImage
;
73 void DemoItem::setNeverVisible(bool never
)
77 this->neverVisible = never;
79 this->setVisible(false);
80 QList<QGraphicsItem *> c = children();
81 for (int i=0; i<c.size(); i++){
82 DemoItem *d = dynamic_cast<DemoItem *>(c[i]); // Don't use dynamic cast because it needs RTTI support.
84 d->setNeverVisible(true);
86 c[i]->setVisible(false);
93 void DemoItem::setRecursiveVisible(bool visible
){
94 if (visible
&& this->neverVisible
){
95 this->setVisible(false);
99 this->setVisible(visible
);
100 QList
<QGraphicsItem
*> c
= children();
101 for (int i
=0; i
<c
.size(); i
++){
102 // DemoItem *d = dynamic_cast<DemoItem *>(c[i]);
104 // d->setRecursiveVisible(visible);
106 c
[i
]->setVisible(visible
);
111 void DemoItem::useGuide(Guide
*guide
, float startFrame
)
113 this->startFrame
= startFrame
;
114 this->guideFrame
= startFrame
;
115 while (this->guideFrame
> guide
->startLength
+ guide
->length()){
116 if (guide
->nextGuide
== guide
->firstGuide
)
119 guide
= guide
->nextGuide
;
121 this->currGuide
= guide
;
124 void DemoItem::guideAdvance(float distance
)
126 this->guideFrame
+= distance
;
127 while (this->guideFrame
> this->currGuide
->startLength
+ this->currGuide
->length()){
128 this->currGuide
= this->currGuide
->nextGuide
;
129 if (this->currGuide
== this->currGuide
->firstGuide
)
130 this->guideFrame
-= this->currGuide
->lengthAll();
134 void DemoItem::guideMove(float moveSpeed
)
136 this->currGuide
->guide(this, moveSpeed
);
139 void DemoItem::setPosUsingSheepDog(const QPointF
&dest
, const QRectF
&sceneFence
)
142 if (sceneFence
.isNull())
145 // I agree. This is not the optimal way of doing it.
146 // But don't want for use time on it now....
147 float itemWidth
= this->boundingRect().width();
148 float itemHeight
= this->boundingRect().height();
149 float fenceRight
= sceneFence
.x() + sceneFence
.width();
150 float fenceBottom
= sceneFence
.y() + sceneFence
.height();
152 if (this->scenePos().x() < sceneFence
.x()) this->moveBy(this->mapFromScene(QPointF(sceneFence
.x(), 0)).x(), 0);
153 if (this->scenePos().x() > fenceRight
- itemWidth
) this->moveBy(this->mapFromScene(QPointF(fenceRight
- itemWidth
, 0)).x(), 0);
154 if (this->scenePos().y() < sceneFence
.y()) this->moveBy(0, this->mapFromScene(QPointF(0, sceneFence
.y())).y());
155 if (this->scenePos().y() > fenceBottom
- itemHeight
) this->moveBy(0, this->mapFromScene(QPointF(0, fenceBottom
- itemHeight
)).y());
158 void DemoItem::setGuidedPos(const QPointF
&pos
)
160 this->guidedPos
= pos
;
163 QPointF
DemoItem::getGuidedPos()
165 return this->guidedPos
;
168 void DemoItem::switchGuide(Guide
*guide
)
170 this->currGuide
= guide
;
171 this->guideFrame
= 0;
174 bool DemoItem::inTransition()
176 if (this->currentAnimation
)
177 return this->currentAnimation
->running();
182 void DemoItem::setMatrix(const QMatrix
&matrix
)
184 DemoItem::matrix
= matrix
;
187 void DemoItem::useSharedImage(const QString
&hashKey
)
189 this->hashKey
= hashKey
;
190 if (!sharedImageHash
.contains(hashKey
))
191 sharedImageHash
.insert(hashKey
, this->sharedImage
);
193 if(--this->sharedImage
->refCount
== 0)
194 delete this->sharedImage
;
195 this->sharedImage
= sharedImageHash
.value(hashKey
);
196 ++this->sharedImage
->refCount
;
200 bool DemoItem::validateImage()
202 if ((this->sharedImage
->matrix
!= DemoItem::matrix
&& !Colors::noRescale
) || !(this->sharedImage
->image
|| this->sharedImage
->pixmap
)){
203 // (Re)create image according to new matrix
204 delete this->sharedImage
->image
;
205 this->sharedImage
->image
= 0;
206 delete this->sharedImage
->pixmap
;
207 this->sharedImage
->pixmap
= 0;
208 this->sharedImage
->matrix
= DemoItem::matrix
;
210 // Let subclass create and draw a new image according to the new matrix
211 QImage
*image
= this->createImage(Colors::noRescale
? QMatrix() : DemoItem::matrix
);
213 if (Colors::showBoundingRect
){
214 // draw red transparent rect
215 QPainter
painter(image
);
216 painter
.fillRect(image
->rect(), QColor(255, 0, 0, 50));
220 this->sharedImage
->unscaledBoundingRect
= this->sharedImage
->matrix
.inverted().mapRect(image
->rect());
221 if (Colors::usePixmaps
){
223 this->sharedImage
->pixmap
= new QPixmap(1, 1);
225 this->sharedImage
->pixmap
= new QPixmap(image
->size());
226 this->sharedImage
->pixmap
->fill(QColor(0, 0, 0, 0));
227 QPainter
painter(this->sharedImage
->pixmap
);
228 painter
.drawImage(0, 0, *image
);
231 this->sharedImage
->image
= image
;
240 QRectF
DemoItem::boundingRect() const
242 const_cast<DemoItem
*>(this)->validateImage();
243 return this->sharedImage
->unscaledBoundingRect
;
246 void DemoItem::paint(QPainter
*painter
, const QStyleOptionGraphicsItem
*option
, QWidget
*widget
)
251 if (this->validateImage()){
253 bool wasSmoothPixmapTransform
= painter
->testRenderHint(QPainter::SmoothPixmapTransform
);
254 painter
->setRenderHint(QPainter::SmoothPixmapTransform
);
256 if (Colors::noRescale
){
257 // Let the painter scale the image for us.
258 // This may degrade both quality and performance
259 if (this->sharedImage
->image
)
260 painter
->drawImage(this->pos(), *this->sharedImage
->image
);
262 painter
->drawPixmap(this->pos(), *this->sharedImage
->pixmap
);
265 QMatrix m
= painter
->worldMatrix();
266 painter
->setWorldMatrix(QMatrix());
267 float x
= this->noSubPixeling
? qRound(m
.dx()) : m
.dx();
268 float y
= this->noSubPixeling
? qRound(m
.dy()) : m
.dy();
269 if (this->sharedImage
->image
)
270 painter
->drawImage(QPointF(x
, y
), *this->sharedImage
->image
);
272 painter
->drawPixmap(QPointF(x
, y
), *this->sharedImage
->pixmap
);
275 if (!wasSmoothPixmapTransform
) {
276 painter
->setRenderHint(QPainter::SmoothPixmapTransform
, false);