- Improved tweening support
[yamf.git] / yamf / model / scene.cpp
blob9492ca023cd14c196f2c88bb1119c0f788c14e24
1 /***************************************************************************
2 * Copyright (C) 2005 by David Cuadrado *
3 * krawek@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program 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 *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "scene.h"
22 #include <dcore/debug.h>
24 #include <QDir>
25 #include <QGraphicsItem>
26 #include <QSet>
28 #include "object.h"
29 #include "layer.h"
31 #include "audiolayer.h"
33 #include "item/group.h"
34 #include "item/builder.h"
36 #include "model/command/manager.h"
37 #include "model/command/insertlayer.h"
38 #include "model/command/removelayer.h"
39 #include "model/command/movelayer.h"
41 #include "model/command/renamescene.h"
43 #include "yamf/model/audiolayer.h"
45 namespace YAMF {
46 namespace Model {
48 struct Scene::Private
50 Layers layers;
52 AudioLayers audioLayers;
54 QString name;
55 bool isLocked;
56 int layerCount;
57 bool isVisible;
59 QSet<Object *> tweeningObjects;
60 QSet<Object *> alwaysVisible;
64 /**
65 * Constructor por defecto
67 Scene::Scene(Project *parent, const QString &name) : QObject(parent), d(new Private)
69 d->name = name;
70 d->isLocked = false;
71 d->layerCount = 0;
72 d->isVisible = true;
75 /**
76 * Destructor
78 Scene::~Scene()
80 D_END;
82 d->layers.clear(true);
84 delete d;
87 /**
88 * Pone un nombre a la escena
90 void Scene::setSceneName(const QString &name)
92 if(name != d->name)
94 Command::RenameScene *cmd = new Command::RenameScene(this, name, &d->name);
95 project()->commandManager()->addCommand(cmd);
99 /**
100 * retorna el nombre de la escena
102 QString Scene::sceneName() const
104 return d->name;
108 * Bloquea la escena
110 void Scene::setLocked(bool isLocked)
112 d->isLocked = isLocked;
116 * Returna verdadero cuando la escena esta bloqueada
118 bool Scene::isLocked() const
120 return d->isLocked;
124 * @~spanish
125 * Cambia la visibilidad de la escena.
126 * Si @p isVisible es verdadero permite la visualización del marco de lo contrario lo oculta.
128 void Scene::setVisible(bool isVisible)
130 d->isVisible = isVisible;
134 * @~spanish
135 * Retorna verdadero si la escena es visible, de lo contrario retorna falso.
137 bool Scene::isVisible() const
139 return d->isVisible;
143 * Retorna la lista de layers
145 Layers Scene::layers() const
147 return d->layers;
151 * @~spanish
152 * Retorna los layers de audio que tiene la escena.
154 AudioLayers Scene::audioLayers() const
156 return d->audioLayers;
160 * @~spanish
161 * Crea una capa y la inserta, en la posición @p visualIndex y con el nombre name;
162 * por defecto añadirá la capa al final de la escena.
164 AudioLayer *Scene::createAudioLayer(int position, const QString &name)
166 D_FUNCINFO << position;
168 AudioLayer *layer = new AudioLayer(this, name);
170 insertLayer(position, layer);
171 layer->setLayerName(tr("Sound layer %1").arg(d->layerCount+1));
173 return layer;
177 * @~spanish
178 * Remueve la capa que esta en la posición @p visualIndex.
179 * FIXME
181 bool Scene::removeLayer( int visualIndex)
183 Layer *layer = this->layer(visualIndex);
184 if ( layer )
186 d->layers.removeAll(visualIndex);
187 delete layer;
188 return true;
191 return false;
196 * Retorna el layer que se encuentra en la posición indicada
197 * @param position
198 * @return
200 Layer *Scene::layer(int visualIndex) const
202 if ( !d->layers.containsVisual(visualIndex) )
204 D_FUNCINFO << " FATAL ERROR: index out of bound " << visualIndex;
205 return 0;
208 return d->layers.visualValue(visualIndex);
212 * @~spanish
213 * Crea una capa de audio y la inserta, en la posición @p visualIndex y con el nombre name;
214 * por defecto añadirá la capa de audio al final de la escena.
216 Model::Layer *Scene::createLayer(int visualIndex, const QString &name)
218 QString layerName = name;
219 if( layerName.isEmpty() )
221 layerName = tr("Layer %1").arg(d->layerCount+1);
224 Model::Layer *layer = new Model::Layer(this, layerName);
226 insertLayer(visualIndex, layer);
227 // layer->setLayerName(layerName);
229 return layer;
233 * @~spanish
234 * Inserte la capa @p layer en la posición @p visualIndex a la escena.
236 void Scene::insertLayer(int visualIndex, Model::Layer *layer)
238 Command::InsertLayer *cmd = new Command::InsertLayer(layer, &d->layers, visualIndex);
239 project()->commandManager()->addCommand(cmd);
241 d->layerCount++;
245 * @~spanish
246 * Añade la capa @p layer a la escena.
248 void Scene::addLayer(Model::Layer *layer)
250 Command::InsertLayer *cmd = new Command::InsertLayer(layer, &d->layers);
251 project()->commandManager()->addCommand(cmd);
253 d->layerCount++;
257 * @~spanish
258 * Remueve la capa @p layer de la escena.
260 void Scene::removeLayer(Model::Layer *layer)
262 Command::RemoveLayer *cmd = new Command::RemoveLayer(layer, &d->layers);
263 project()->commandManager()->addCommand(cmd);
268 * Mueve el layer a la posicion indicada
270 bool Scene::moveLayer(int from, int to)
272 if ( from < 0 || from >= d->layers.count() || to < 0 || to >= d->layers.count() )
274 return false;
277 Command::MoveLayer *cmd = new Command::MoveLayer(this, from, to, &d->layers);
278 project()->commandManager()->addCommand(cmd);
280 return true;
284 * Retorna la posición logica de la escena.
286 int Scene::logicalIndex() const
288 if ( Project *project = dynamic_cast<Project *>(parent()) )
290 return project->logicalIndexOf(const_cast<Scene *>(this) );
293 return -1;
297 * Retorna la posición visual de la escena.
299 int Scene::visualIndex() const
301 if ( Project *project = dynamic_cast<Project *>(parent()) )
303 return project->visualIndexOf(const_cast<Scene *>(this) );
306 return -1;
310 * Retorna la posición visual de la capa @p layer.
312 int Scene::visualIndexOf(Layer *layer) const
314 return d->layers.visualIndex(layer);
318 * Retorna la posición logica de la capa @p layer.
320 int Scene::logicalIndexOf(Layer *layer) const
322 return d->layers.logicalIndex(layer);
326 * @~spanish
327 * Retorna el proyecto en el que esta la escena.
329 Project *Scene::project() const
331 return static_cast<Project *>(parent());
334 void Scene::addTweeningObject(Object *object)
336 d->tweeningObjects << object;
339 void Scene::removeTweeningObject(Object *object)
341 d->tweeningObjects.remove(object);
344 void Scene::setAlwaysVisible(Object *object, bool visible)
346 if( visible)
348 d->alwaysVisible << object;
350 else
352 d->alwaysVisible.remove(object);
356 QList<Object *> Scene::alwaysVisible() const
358 return d->alwaysVisible.toList();
361 QList<Object *> Scene::tweeningObjects() const
363 return d->tweeningObjects.toList();
366 bool Scene::containsTweeningObject(Object *object) const
368 return d->tweeningObjects.contains(object);
371 Model::Object *Scene::tweeningObject(QGraphicsItem *item) const
373 Model::Object *ret = 0;
374 foreach(Model::Object *obj, d->tweeningObjects )
376 if( obj->item() == item )
378 ret = obj;
379 break;
383 return ret;
386 Model::Location Scene::location() const
388 Model::Location loc;
389 loc.setValue(Location::Scene, visualIndex());
391 return loc;
395 * @~spanish
396 * Construye la escena a partir del xml.
398 void Scene::fromXml(const QString &xml )
400 QDomDocument document;
402 if (! document.setContent(xml) )
404 return;
407 QDomElement root = document.documentElement();
408 QDomNode n = root.firstChild();
409 setSceneName( root.attribute( "name", sceneName()) );
411 while( !n.isNull() )
413 QDomElement e = n.toElement();
415 if(!e.isNull())
417 if ( e.tagName() == "layer" )
419 int pos = d->layers.count();
422 QString newDoc;
425 QTextStream ts(&newDoc);
426 ts << n;
429 QDomDocument doc;
430 if( !doc.setContent(newDoc) ) return;
432 QDomElement root = doc.documentElement();
433 QString name = root.attribute("name");
434 int type = root.attribute("type").toInt();
437 Layer *layer = 0;
439 switch(type)
441 case Layer::Audio:
443 layer = createAudioLayer(-1, name);
445 break;
446 default:
448 layer = createLayer(-1, name);
450 break;
453 layer->fromXml( newDoc );
458 n = n.nextSibling();
463 * @~spanish
464 * Convierte la escena a un documento xml.
466 QDomElement Scene::toXml(QDomDocument &doc) const
468 QDomElement root = doc.createElement("scene");
469 root.setAttribute("name", d->name );
471 foreach(Layer *layer, d->layers.visualValues())
473 root.appendChild( layer->toXml(doc) );
476 foreach(AudioLayer *sound, d->audioLayers)
478 root.appendChild(sound->toXml(doc));
482 return root;