Removing unnecessary chunking and stat'ing when reading QIODevice
[qt-netbsd.git] / demos / qtdemo / itemcircleanimation.cpp
blob8c94eb7c0adc66db72bca764482350f385434dc7
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 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 demonstration applications of the Qt Toolkit.
8 **
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
14 ** this package.
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.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include "itemcircleanimation.h"
43 #include "demoitemanimation.h"
44 #include "colors.h"
45 #include "menumanager.h"
46 #include "mainwindow.h"
47 #include "menumanager.h"
49 static QGraphicsScene *sscene;
51 //////////////////// POST EFFECT STUFF ////////////////////////////////////////
53 class TickerPostEffect
55 public:
56 virtual ~TickerPostEffect(){};
57 virtual void tick(float){};
58 virtual void transform(DemoItem *, QPointF &){};
61 class PostRotateXY : public TickerPostEffect
63 public:
64 float currRotX, currRotY;
65 float speedx, speedy, curvx, curvy;
67 PostRotateXY(float speedx, float speedy, float curvx, float curvy)
68 : currRotX(0), currRotY(0),
69 speedx(speedx), speedy(speedy),
70 curvx(curvx), curvy(curvy){};
72 void tick(float adjust)
74 currRotX += speedx * adjust;
75 currRotY += speedy * adjust;
78 void transform(DemoItem *item, QPointF &pos)
80 DemoItem *parent = (DemoItem *) item->parentItem();
81 QPointF center = parent->boundingRect().center();
82 pos.setX(center.x() + (pos.x() - center.x()) * cos(currRotX + pos.x() * curvx));
83 pos.setY(center.y() + (pos.y() - center.y()) * cos(currRotY + pos.y() * curvy));
87 class PostRotateXYTwist : public TickerPostEffect
89 public:
90 float currRotX, currRotY;
91 float speedx, speedy, curvx, curvy;
93 PostRotateXYTwist(float speedx, float speedy, float curvx, float curvy)
94 : currRotX(0), currRotY(0),
95 speedx(speedx), speedy(speedy),
96 curvx(curvx), curvy(curvy){};
98 void tick(float adjust)
100 currRotX += speedx * adjust;
101 currRotY += speedy * adjust;
104 void transform(DemoItem *item, QPointF &pos)
106 DemoItem *parent = (DemoItem *) item->parentItem();
107 QPointF center = parent->boundingRect().center();
108 pos.setX(center.x() + (pos.x() - center.x()) * cos(currRotX + pos.y() * curvx));
109 pos.setY(center.y() + (pos.y() - center.y()) * cos(currRotY + pos.x() * curvy));
113 //////////////////// TICKER EFFECT STUFF //////////////////////////////////////
115 class TickerEffect
117 TickerPostEffect *postEffect;
118 public:
119 enum EffectStatus{Normal, Intro, Outro} status;
120 LetterList *letters;
121 float morphSpeed, moveSpeed;
122 float normalMorphSpeed, normalMoveSpeed;
123 bool useSheepDog, morphBetweenModels;
125 TickerEffect(LetterList *letters)
126 : postEffect(new TickerPostEffect()), status(Intro), letters(letters),
127 morphSpeed(Colors::tickerMorphSpeed), moveSpeed(Colors::tickerMoveSpeed),
128 normalMorphSpeed(Colors::tickerMorphSpeed), normalMoveSpeed(Colors::tickerMoveSpeed),
129 useSheepDog(true), morphBetweenModels(!Colors::noTickerMorph){}
131 void setPostEffect(TickerPostEffect *effect)
133 delete postEffect;
134 postEffect = effect;
137 virtual ~TickerEffect()
139 delete postEffect;
142 void slowDownAfterIntro(float adjust)
144 if (morphBetweenModels){
145 if (status == Intro){
146 float dec = 0.1 * adjust;
147 moveSpeed -= dec;
148 if (moveSpeed < Colors::tickerMoveSpeed){
149 moveSpeed = normalMoveSpeed;
150 morphSpeed = normalMorphSpeed;
151 status = Normal;
157 void moveLetters(float adjust)
159 float adaptedMoveSpeed = this->moveSpeed * adjust;
160 float adaptedMorphSpeed = this->morphSpeed * adjust;
161 postEffect->tick(adjust);
163 for (int i=0; i<letters->size(); i++){
164 LetterItem *letter = letters->at(i);
165 letter->guideAdvance(this->morphBetweenModels ? adaptedMoveSpeed : Colors::tickerMoveSpeed);
166 letter->guideMove(this->morphBetweenModels ? adaptedMorphSpeed : -1);
168 QPointF pos = letter->getGuidedPos();
169 postEffect->transform(letter, pos);
171 if (useSheepDog)
172 letter->setPosUsingSheepDog(pos, QRectF(0, 0, 800, 600));
173 else
174 letter->setPos(pos);
178 virtual void tick(float adjust)
180 slowDownAfterIntro(adjust);
181 moveLetters(adjust);
186 class EffectWhirlWind : public TickerEffect
188 public:
189 EffectWhirlWind(LetterList *letters) : TickerEffect(letters)
191 moveSpeed = 50;
192 for (int i=0; i<this->letters->size(); i++){
193 LetterItem *letter = this->letters->at(i);
194 letter->setGuidedPos(QPointF(0, 100));
199 class EffectSnake : public TickerEffect
201 public:
202 EffectSnake(LetterList *letters) : TickerEffect(letters)
204 moveSpeed = 40;
205 for (int i=0; i<this->letters->size(); i++){
206 LetterItem *letter = this->letters->at(i);
207 letter->setGuidedPos(QPointF(0, -250 - (i * 5)));
212 class EffectScan : public TickerEffect
214 public:
215 EffectScan(LetterList *letters) : TickerEffect(letters)
217 for (int i=0; i<this->letters->size(); i++){
218 LetterItem *letter = this->letters->at(i);
219 letter->setGuidedPos(QPointF(100, -300));
224 class EffectRaindrops : public TickerEffect
226 public:
227 EffectRaindrops(LetterList *letters) : TickerEffect(letters)
229 for (int i=0; i<this->letters->size(); i++){
230 LetterItem *letter = this->letters->at(i);
231 letter->setGuidedPos(QPointF(-100 + rand() % 200, - 200.0f - rand() % 1300));
236 class EffectLine : public TickerEffect
238 public:
239 EffectLine(LetterList *letters) : TickerEffect(letters)
241 for (int i=0; i<this->letters->size(); i++){
242 LetterItem *letter = this->letters->at(i);
243 letter->setGuidedPos(QPointF(100, 500.0f + i * 20));
248 //////////////////// TICKER STUFF /////////////////////////////////////////////
250 ItemCircleAnimation::ItemCircleAnimation(QGraphicsScene *scene, QGraphicsItem *parent)
251 : DemoItem(scene, parent)
253 sscene = scene;
254 this->letterCount = Colors::tickerLetterCount;
255 this->scale = 1;
256 this->showCount = -1;
257 this->tickOnPaint = false;
258 this->paused = false;
259 this->doIntroTransitions = true;
260 this->setAcceptsHoverEvents(true);
261 this->setCursor(Qt::OpenHandCursor);
262 this->setupGuides();
263 this->setupLetters();
264 this->useGuideQt();
265 this->effect = 0;//new TickerEffect(this->letterList);
268 ItemCircleAnimation::~ItemCircleAnimation()
270 delete this->letterList;
271 delete this->qtGuide1;
272 delete this->qtGuide2;
273 delete this->qtGuide3;
274 delete this->effect;
277 void ItemCircleAnimation::createLetter(char c)
279 LetterItem *letter = new LetterItem(c, sscene, this);
280 this->letterList->append(letter);
283 void ItemCircleAnimation::setupLetters()
285 this->letterList = new LetterList();
287 QString s = Colors::tickerText;
288 int len = s.length();
289 int i = 0;
290 for (; i < this->letterCount - len; i += len)
291 for (int l=0; l<len; l++)
292 createLetter(s[l].toLatin1());
294 // Fill inn with blanks:
295 for (; i < this->letterCount; ++i)
296 createLetter(' ');
299 void ItemCircleAnimation::setupGuides()
301 int x = 0;
302 int y = 20;
304 this->qtGuide1 = new GuideCircle(QRectF(x, y, 260, 260), -36, 342);
305 new GuideLine(QPointF(x + 240, y + 268), this->qtGuide1);
306 new GuideLine(QPointF(x + 265, y + 246), this->qtGuide1);
307 new GuideLine(QPointF(x + 158, y + 134), this->qtGuide1);
308 new GuideLine(QPointF(x + 184, y + 109), this->qtGuide1);
309 new GuideLine(QPointF(x + 160, y + 82), this->qtGuide1);
310 new GuideLine(QPointF(x + 77, y + 163), this->qtGuide1); // T-top
311 new GuideLine(QPointF(x + 100, y + 190), this->qtGuide1);
312 new GuideLine(QPointF(x + 132, y + 159), this->qtGuide1);
313 new GuideLine(QPointF(x + 188, y + 211), this->qtGuide1);
314 new GuideCircle(QRectF(x + 30, y + 30, 200, 200), -30, 336, GuideCircle::CW, this->qtGuide1);
315 new GuideLine(QPointF(x + 238, y + 201), this->qtGuide1);
317 y = 30;
318 this->qtGuide2 = new GuideCircle(QRectF(x + 30, y + 30, 200, 200), 135, 270, GuideCircle::CCW);
319 new GuideLine(QPointF(x + 222, y + 38), this->qtGuide2);
320 new GuideCircle(QRectF(x, y, 260, 260), 135, 270, GuideCircle::CW, this->qtGuide2);
321 new GuideLine(QPointF(x + 59, y + 59), this->qtGuide2);
323 x = 115;
324 y = 10;
325 this->qtGuide3 = new GuideLine(QLineF(x, y, x + 30, y));
326 new GuideLine(QPointF(x + 30, y + 170), this->qtGuide3);
327 new GuideLine(QPointF(x, y + 170), this->qtGuide3);
328 new GuideLine(QPointF(x, y), this->qtGuide3);
330 this->qtGuide1->setFence(QRectF(0, 0, 800, 600));
331 this->qtGuide2->setFence(QRectF(0, 0, 800, 600));
332 this->qtGuide3->setFence(QRectF(0, 0, 800, 600));
335 void ItemCircleAnimation::useGuide(Guide *guide, int firstLetter, int lastLetter)
337 float padding = guide->lengthAll() / float(lastLetter - firstLetter);
338 for (int i=firstLetter; i<lastLetter; i++){
339 LetterItem *letter = this->letterList->at(i);
340 letter->useGuide(guide, (i - firstLetter) * padding);
344 void ItemCircleAnimation::useGuideQt()
346 if (this->currGuide != this->qtGuide1){
347 this->useGuide(qtGuide1, 0, this->letterCount);
348 this->currGuide = qtGuide1;
352 void ItemCircleAnimation::useGuideTt()
354 if (this->currGuide != this->qtGuide2){
355 int split = int(this->letterCount * 5.0 / 7.0);
356 this->useGuide(qtGuide2, 0, split);
357 this->useGuide(qtGuide3, split, this->letterCount);
358 this->currGuide = qtGuide2;
362 QRectF ItemCircleAnimation::boundingRect() const
364 return QRectF(0, 0, 300, 320);
367 void ItemCircleAnimation::prepare()
371 void ItemCircleAnimation::switchToNextEffect()
373 ++this->showCount;
374 delete this->effect;
376 switch (this->showCount){
377 case 1:
378 this->effect = new EffectSnake(this->letterList);
379 break;
380 case 2:
381 this->effect = new EffectLine(this->letterList);
382 this->effect->setPostEffect(new PostRotateXYTwist(0.01f, 0.0f, 0.003f, 0.0f));
383 break;
384 case 3:
385 this->effect = new EffectRaindrops(this->letterList);
386 this->effect->setPostEffect(new PostRotateXYTwist(0.01f, 0.005f, 0.003f, 0.003f));
387 break;
388 case 4:
389 this->effect = new EffectScan(this->letterList);
390 this->effect->normalMoveSpeed = 0;
391 this->effect->setPostEffect(new PostRotateXY(0.008f, 0.0f, 0.005f, 0.0f));
392 break;
393 default:
394 this->showCount = 0;
395 this->effect = new EffectWhirlWind(this->letterList);
399 void ItemCircleAnimation::animationStarted(int id)
401 if (id == DemoItemAnimation::ANIM_IN){
402 if (this->doIntroTransitions){
403 // Make all letters dissapear
404 for (int i=0; i<this->letterList->size(); i++){
405 LetterItem *letter = this->letterList->at(i);
406 letter->setPos(1000, 0);
408 this->switchToNextEffect();
409 this->useGuideQt();
410 this->scale = 1;
411 // The first time we run, we have a rather large
412 // delay to perform benchmark before the ticker shows.
413 // But now, since we are showing, use a more appropriate value:
414 this->currentAnimation->startDelay = 1500;
417 else if (this->effect)
418 this->effect->useSheepDog = false;
420 this->tickTimer = QTime::currentTime();
423 void ItemCircleAnimation::animationStopped(int)
425 // Nothing to do.
428 void ItemCircleAnimation::swapModel(){
429 if (this->currGuide == this->qtGuide2)
430 this->useGuideQt();
431 else
432 this->useGuideTt();
435 void ItemCircleAnimation::hoverEnterEvent(QGraphicsSceneHoverEvent *)
437 // Skip swap here to enhance ticker dragging
438 // this->swapModel();
441 void ItemCircleAnimation::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
443 this->swapModel();
446 void ItemCircleAnimation::setTickerScale(float s)
448 this->scale = s;
449 qtGuide1->setScale(this->scale, this->scale);
450 qtGuide2->setScale(this->scale, this->scale);
451 qtGuide3->setScale(this->scale, this->scale);
454 void ItemCircleAnimation::mousePressEvent(QGraphicsSceneMouseEvent *event)
456 this->mouseMoveLastPosition = event->scenePos();
457 if (event->button() == Qt::LeftButton)
458 this->setCursor(Qt::ClosedHandCursor);
459 else
460 this->switchToNextEffect();
463 void ItemCircleAnimation::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
465 if (event->button() == Qt::LeftButton)
466 this->setCursor(Qt::OpenHandCursor);
469 void ItemCircleAnimation::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
471 QPointF newPosition = event->scenePos();
472 this->setPosUsingSheepDog(this->pos() + newPosition - this->mouseMoveLastPosition, QRectF(-260, -280, 1350, 1160));
473 this->mouseMoveLastPosition = newPosition;
476 void ItemCircleAnimation::wheelEvent(QGraphicsSceneWheelEvent *event)
478 this->effect->moveSpeed = this->effect->moveSpeed + (event->delta() > 0 ? -0.20 : 0.20);
479 if (this->effect->moveSpeed < 0)
480 this->effect->moveSpeed = 0;
483 void ItemCircleAnimation::pause(bool on)
485 this->paused = on;
486 this->tickTimer = QTime::currentTime();
489 void ItemCircleAnimation::tick()
491 if (this->paused || !this->effect)
492 return;
494 float t = this->tickTimer.msecsTo(QTime::currentTime());
495 this->tickTimer = QTime::currentTime();
496 this->effect->tick(t/10.0f);
499 void ItemCircleAnimation::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
501 if (this->tickOnPaint)
502 tick();