Improved Render::Area
[yamf.git] / yamf / render / area.cpp
blob79ad5a124ba7329238beb9a1ef0a704da38883f9
1 /***************************************************************************
2 * Copyright (C) 2007 David Cuadrado *
3 * krawek@gmail.com *
4 * *
5 * This library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Lesser General Public *
7 * License as published by the Free Software Foundation; either *
8 * version 2.1 of the License, or (at your option) any later version. *
9 * *
10 * This library is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 * Lesser General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Lesser General Public *
16 * License along with this library; if not, write to the Free Software *
17 * Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
21 #include "area.h"
23 #include "yamf/render/renderer.h"
24 #include "yamf/drawing/photogram.h"
25 #include "yamf/common/abstractserializable.h"
27 // DLib
28 #include <dcore/debug.h>
30 // Qt
31 #include <QTimeLine>
32 #include <QResizeEvent>
33 #include <QStyleOptionGraphicsItem>
35 namespace YAMF {
37 namespace Render {
39 struct Area::Private
41 Private() : renderer(new Renderer), fps(24), lastScaleX(1.0), lastScaleY(1.0) {}
42 ~Private() { delete renderer; delete timeLine; }
44 Renderer *renderer;
45 QTimeLine *timeLine;
47 QList<YAMF::Model::Scene *> scenes;
48 QList<YAMF::Model::Scene *>::iterator currentScene;
50 int fps;
52 double lastScaleX;
53 double lastScaleY;
56 Area::Area(QWidget *parent)
57 : QGraphicsView(parent), d(new Private)
59 d->currentScene = d->scenes.end();
61 d->timeLine = new QTimeLine;
62 d->timeLine->setCurveShape(QTimeLine::LinearCurve);
64 connect(d->timeLine, SIGNAL(frameChanged(int)), this, SLOT(setFrame(int)));
65 connect(d->timeLine, SIGNAL(finished()), this, SLOT(nextScene()));
67 setScene(d->renderer->photogram());
69 QRectF rect(0, 0, this->width(), this->height());
70 scale(rect);
74 Area::~Area()
76 delete d;
79 void Area::setScenes(const QList<YAMF::Model::Scene *> &scenes)
81 if( scenes.isEmpty() ) return;
83 d->scenes = scenes;
85 d->currentScene = d->scenes.begin();
86 d->renderer->setScene(d->scenes.first());
87 setFps(d->fps);
90 void Area::start()
92 if( d->scenes.isEmpty() ) return;
94 d->timeLine->start();
97 void Area::stop()
99 d->timeLine->stop();
102 int Area::fps() const
104 return d->fps;
107 void Area::setFps(int fps)
109 d->fps = fps;
112 int total = d->renderer->totalPhotograms();
113 d->timeLine->setFrameRange(0, total);
114 d->timeLine->setDuration((1000/fps) * total);
117 void Area::setFrame(int frame)
119 d->renderer->setCurrentPhotogram(frame);
122 void Area::nextScene()
124 if( d->scenes.isEmpty() ) return;
126 d->currentScene++;
128 if( d->currentScene >= d->scenes.end() )
130 d->currentScene = d->scenes.begin();
131 d->renderer->setScene(*d->currentScene);
132 setFps(d->fps);
134 emit finished();
136 else
138 d->renderer->setScene(*d->currentScene);
139 setFps(d->fps);
140 d->timeLine->start();
144 void Area::scale(const QRectF &rect, Qt::AspectRatioMode aspectRatio )
146 QRectF sceneRect = d->renderer->photogram()->sceneRect();
148 if( sceneRect.width() == 0 || sceneRect.height() == 0 ) return;
150 double sx = 1, sy = 1;
152 sx = static_cast<double>(rect.width()) / static_cast<double>(sceneRect.width());
153 sy = static_cast<double>(rect.height()) / static_cast<double>(sceneRect.height());
155 if(sx > 0 && sy > 0)
158 double restoreScaleX = 1.0/d->lastScaleX;
159 double restoreScaleY = 1.0/d->lastScaleY;
160 QGraphicsView::scale(restoreScaleX, restoreScaleY);
163 switch(aspectRatio)
165 case Qt::IgnoreAspectRatio:
167 QGraphicsView::scale(sx, sy);
169 break;
170 case Qt::KeepAspectRatio:
172 float factor = qMin(sx, sy);
173 QGraphicsView::scale(factor, factor);
175 break;
176 case Qt::KeepAspectRatioByExpanding:
178 float factor = qMax(sx, sy);
179 QGraphicsView::scale(factor, factor);
181 break;
184 d->lastScaleX = sx;
185 d->lastScaleY = sy;
189 void Area::resizeEvent( QResizeEvent * event )
191 scale(QRectF(QPoint(0,0), event->size()));
194 void Area::drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[])
196 QList<QGraphicsItem *> list;
197 for(int i = 0; i < numItems; i++)
199 if(dynamic_cast<Common::AbstractSerializable *>(items[i]))
201 list << items[i];
205 QGraphicsItem **drawitems = new QGraphicsItem *[list.size()];
207 int count = 0;
208 foreach(QGraphicsItem *item, list)
210 drawitems[count] = item;
211 count++;
214 QGraphicsView::drawItems(painter, list.size(), drawitems, options);
215 delete[] drawitems;