1 /***************************************************************************
2 * Copyright (C) 2005 by David Cuadrado *
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. *
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. *
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 ***************************************************************************/
24 #include <dcore/debug.h>
26 #include <QGraphicsItem>
30 #include "item/builder.h"
31 #include "model/command/manager.h"
32 #include "model/command/addobject.h"
33 #include "model/command/removeobject.h"
34 #include "model/command/lockframe.h"
35 #include "model/command/changeframevisibility.h"
36 #include "model/command/renameframe.h"
38 #include "model/library.h"
39 #include "model/object.h"
40 #include "model/objectgroup.h"
42 #include "item/group.h"
43 #include "item/tweener.h"
45 #define INVALID_Z -10000
53 Private() : objectCount(0)
60 GraphicObjects graphics
;
65 ObjectGroup
*createObjectGroup(Frame
*frame
, QGraphicsItem
*item
)
67 ObjectGroup
*oGroup
= new ObjectGroup(frame
);
68 if(Item::Group
*group
= static_cast<Item::Group
* >(item
))
70 foreach(QGraphicsItem
*child
, group
->childs())
72 if(child
->type() == Item::Group::Type
)
74 ObjectGroup
*ocGroup
= createObjectGroup(frame
, child
);
75 oGroup
->addToGroup(ocGroup
);
80 Object
*object
= new Object(child
, frame
);
81 oGroup
->addToGroup(object
);
88 void fixZValue( Object
*object
)
90 if( QGraphicsItem
*item
= object
->item() )
92 if( item
->zValue() == INVALID_Z
)
95 foreach(Object
*graphic
, graphics
.values() )
97 if( zMax
< graphic
->item()->zValue() )
99 zMax
= graphic
->item()->zValue();
102 item
->setZValue(zMax
+0.1);
112 * Constructor por defecto
114 Frame::Frame(Layer
*parent
, const QString
& name
) : QObject(parent
), d(new Private
)
128 d
->graphics
.clear(true);
138 d
->graphics
.clear(true);
143 * Pone el nombre del frame
145 void Frame::setFrameName(const QString
&name
)
149 Command::RenameFrame
*cmd
= new Command::RenameFrame(this, name
, &d
->name
);
150 project()->commandManager()->addCommand(cmd
);
156 * Retorna el nombre del frame
158 QString
Frame::frameName() const
165 * Si isLocked es verdadero bloquea el frame, de lo contrario lo desbloquea.
167 void Frame::setLocked(bool isLocked
)
169 if(isLocked
!= d
->isLocked
)
171 Command::LockFrame
*command
= new Command::LockFrame(this, isLocked
, &d
->isLocked
);
172 project()->commandManager()->addCommand(command
);
179 * Returna verdadero cuando el frame esta bloqueado
181 bool Frame::isLocked() const
188 * Cambia la visibilidad del marco.
189 * Si @p isVisible es verdadero permite la visualización del marco de lo contrario lo oculta.
191 void Frame::setVisible(bool isVisible
)
193 if(d
->isVisible
!= isVisible
)
195 Command::ChangeFrameVisibility
*command
= new Command::ChangeFrameVisibility(this, isVisible
, &d
->isVisible
);
196 project()->commandManager()->addCommand(command
);
202 * Retorna verdadero si el marco es visible, de lo contrario retorna falso.
204 bool Frame::isVisible() const
211 * Añade un objeto grafico al marco.
213 void Frame::addObject(Object
*object
)
215 Command::Manager
*commandManager
= project()->commandManager();
217 object
->setParent(this);
219 d
->fixZValue(object
);
221 if( object
->objectName().isEmpty() )
223 object
->setObjectName(tr("Object %1").arg(d
->objectCount
++));
226 Command::AddObject
*command
= new Command::AddObject(object
, &d
->graphics
);
227 commandManager
->addCommand(command
);
232 * Remueve el objeto grafico @p object del marco.
234 void Frame::removeObject(Object
*object
)
236 Command::RemoveObject
*cmd
= new Command::RemoveObject(object
, &d
->graphics
, this);
237 project()->commandManager()->addCommand(cmd
);
239 this->scene()->removeTweeningObject(object
);
244 * Remueve los objetos graficos @p objects del marco.
246 void Frame::removeObjects(const QList
<Object
*> &objects
)
248 Command::RemoveObject
*cmd
= new Command::RemoveObject(objects
, &d
->graphics
, this);
249 project()->commandManager()->addCommand(cmd
);
251 foreach(Object
*object
, objects
)
253 this->scene()->removeTweeningObject(object
);
259 * Remueve los objetos graficos que contiene el ítem @p item del marco.
261 void Frame::removeItem(QGraphicsItem
*item
)
263 int index
= visualIndexOf(item
);
266 removeObject(graphic(index
));
272 * Remueve los objetos graficos que contiene los ítems @p items del marco.
274 void Frame::removeItems(const QList
<QGraphicsItem
*> &items
)
276 QList
<Object
*> objects
;
277 foreach(QGraphicsItem
*item
, items
)
279 int index
= visualIndexOf(item
);
282 objects
<< graphic(index
);
286 if(!objects
.isEmpty())
287 removeObjects(objects
);
292 * Añade el item grafico @p item al marco, retornando el objeto grafico que lo contiene.
294 Object
*Frame::addItem(QGraphicsItem
*item
)
296 Object
*object
= new Object(item
, this);
297 object
->setObjectName(tr("Object %1").arg(d
->objectCount
++));
298 item
->setZValue(INVALID_Z
);
307 * Reemplaza el item que contien el objeto grafico de la posición @p logicalIndex por el ítem @p item..
309 void Frame::replaceItem(int logicalIndex
, QGraphicsItem
*item
)
311 Object
*toReplace
= this->graphic(logicalIndex
);
315 toReplace
->setItem( item
);
321 * Remueve el objeto grafico que esta en la posición @p logicalIndex del marco.
323 void Frame::removeObjectAt(int logicalIndex
)
325 if ( !d
->graphics
.contains(logicalIndex
) )
330 Object
*object
= graphic(logicalIndex
);
331 removeObject(object
);
334 void Frame::detach(Model::Object
*object
)
336 d
->graphics
.remove(object
);
338 QGraphicsItem
*item
= object
->item();
342 QGraphicsScene
*scene
= item
->scene();
346 scene
->removeItem(item
);
351 void Frame::attach(Model::Object
*object
)
353 d
->graphics
.add(object
);
358 * Cambia la posición del objeto grafico de la posición @p currentPosition a la posición @p newPosition.
360 bool Frame::moveItem(int currentPosition
, int newPosition
)
362 D_FUNCINFO
<< "current "<< currentPosition
<< " new " << newPosition
;
363 if(currentPosition
== newPosition
|| currentPosition
< 0 || currentPosition
>= d
->graphics
.count() || newPosition
< 0 || newPosition
>= d
->graphics
.count())
368 if(currentPosition
< newPosition
)
370 for( int i
= currentPosition
; i
< newPosition
; i
++)
372 double tmp
= d
->graphics
.visualValue(i
)->item()->zValue();
373 d
->graphics
.visualValue(i
)->item()->setZValue(d
->graphics
.visualValue(i
+1)->item()->zValue());
374 d
->graphics
.visualValue(i
+1)->item()->setZValue(tmp
);
375 d
->graphics
.moveVisual(i
, i
+1);
380 for( int i
= currentPosition
; i
> newPosition
; i
--)
382 double tmp
= d
->graphics
.visualValue(i
)->item()->zValue();
383 d
->graphics
.visualValue(i
)->item()->setZValue(d
->graphics
.visualValue(i
-1)->item()->zValue());
384 d
->graphics
.visualValue(i
-1)->item()->setZValue(tmp
);
385 d
->graphics
.moveVisual(i
, i
-1);
395 * Retorna los objetos graficos que contiene el marco.
397 GraphicObjects
Frame::graphics() const
404 * Retorna el objeto grafico de la posición @p visualIndex.
406 Object
*Frame::graphic(int visualIndex
) const
408 if ( !d
->graphics
.containsVisual(visualIndex
) )
410 D_FUNCINFO
<< " FATAL ERROR: index out of bound " << visualIndex
<< " FRAME: " << this->visualIndex() << " LAYER: " << layer()->visualIndex();
414 return d
->graphics
.visualValue(visualIndex
);
419 * Retorna el objecto grafico que contiene al item @p item.
421 Object
*Frame::graphic(QGraphicsItem
*item
) const
425 foreach(Object
*object
, d
->graphics
.values() )
427 if (object
->item() == item
)
436 Object
*Frame::findGraphic(QGraphicsItem
*item
) const
438 Object
*object
= graphic(item
);
442 object
= scene()->tweeningObject(item
);
450 * Retorna el item que contiene el objeto grafico de la posición @p visualIndex.
452 QGraphicsItem
*Frame::item(int visualIndex
) const
454 Object
*object
= graphic(visualIndex
);
458 return object
->item();
466 * Obtiene la posición visual del objeto grafico @p object.
468 int Frame::visualIndexOf(Object
*object
) const
470 return d
->graphics
.visualIndex(object
);
475 * Obtiene la posición logica del objeto grafico @p object.
477 int Frame::logicalIndexOf(Object
*object
) const
479 return d
->graphics
.logicalIndex(object
);
484 * Obtiene la posición visual del objeto grafico que contiene al ítem @p item.
486 int Frame::visualIndexOf(QGraphicsItem
*item
) const
488 foreach(Object
*object
, d
->graphics
.values() )
490 if (object
->item() == item
)
492 return d
->graphics
.visualIndex(object
);
500 * Obtiene la posición logica del objeto grafico que contiene al ítem @p item.
502 int Frame::logicalIndexOf(QGraphicsItem
*item
) const
504 foreach(Object
*object
, d
->graphics
.values())
506 if (object
->item() == item
)
508 return d
->graphics
.logicalIndex(object
);
518 * Retorna la posición visual del marco.
520 int Frame::visualIndex() const
522 return layer()->visualIndexOf(const_cast<Frame
*>(this));
528 * Retorna la posición logica del marco.
530 int Frame::logicalIndex() const
532 return layer()->logicalIndexOf(const_cast<Frame
*>(this));
535 Model::Location
Frame::location() const
538 loc
.setValue(Location::Scene
, scene()->visualIndex() );
539 loc
.setValue(Location::Layer
, layer()->visualIndex() );
540 loc
.setValue(Location::Frame
, this->visualIndex() );
548 * Retorna la capa en la que esta el marco.
550 Layer
*Frame::layer() const
552 return static_cast<Layer
*>(parent());
557 * Retorna la escena en la que esta el marco.
559 Scene
*Frame::scene() const
561 return layer()->scene();
567 * Retorna el proyecto en el que esta el marco.
569 Project
*Frame::project() const
571 return layer()->project();
577 * Construye el marco a partir del xml.
579 void Frame::fromXml(const QString
&xml
)
581 QDomDocument document
;
583 if (! document
.setContent(xml
) )
588 QDomElement root
= document
.documentElement();
590 setFrameName( root
.attribute( "name", frameName() ) );
592 QDomNode n
= root
.firstChild();
596 QDomElement e
= n
.toElement();
600 if( e
.tagName() == "object" )
603 QTextStream
ts(&objectXml
);
606 Object
*last
= new Object(this);
607 last
->fromXml(objectXml
);
611 if(last
->item()->type() == Item::Group::Type
)
613 ObjectGroup
*oGroup
= d
->createObjectGroup(this, last
->item());
634 * Convierte el marco a un documento xml.
636 QDomElement
Frame::toXml(QDomDocument
&doc
) const
638 QDomElement root
= doc
.createElement("frame");
639 root
.setAttribute("name", d
->name
);
640 root
.setAttribute("index", visualIndex());
641 int nclones
= layer()->clones(const_cast<Frame
*>(this));
644 root
.setAttribute("clones", nclones
);
647 doc
.appendChild(root
);
649 foreach(Object
*object
, d
->graphics
.visualValues() )
651 if( dynamic_cast<Common::AbstractSerializable
*>(object
->item()) )
653 root
.appendChild( object
->toXml(doc
) );