1 /***************************************************************************
2 * Copyright (C) 2005 by Jorge Cuadrado *
3 * kuadrosxx@gmail.com *
4 * Copyright (C) 2006 by David Cuadrado *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
23 #include "paintarea.h"
25 #include "private/paintarearotator.h"
27 #include <QGraphicsScene>
28 #include <QMouseEvent>
29 #include <QGraphicsSceneMouseEvent>
30 #include <QGraphicsRectItem>
32 #include <QApplication>
34 #include <QStyleOptionGraphicsItem>
40 #include "photogram.h"
41 #include <dgraphics/algorithm.h>
43 #include <dcore/config.h>
44 #include <dcore/debug.h>
45 #include <dgui/application.h>
47 #include <dgui/commandhistory.h>
48 #include <dgui/action.h>
49 #include <dgui/actionmanager.h>
50 #include <dgui/iconloader.h>
54 #include <model/scene.h>
55 #include <model/layer.h>
56 #include <model/frame.h>
57 #include <model/object.h>
58 #include <model/library.h>
60 #include <item/group.h>
61 #include <item/serializer.h>
62 #include "yamf/item/tweenerstep.h"
63 #include "yamf/item/tweener.h"
65 #include "model/command/base.h"
66 #include "model/command/groupitem.h"
67 #include "model/command/ungroupitem.h"
68 #include "model/command/modifyitem.h"
69 #include "model/command/modifysymbol.h"
70 #include "model/command/sendtobackitem.h"
71 #include "model/command/bringtofrontitem.h"
72 #include "model/command/sendbackwardsitem.h"
73 #include "model/command/bringforwardsitem.h"
74 #include "model/command/manager.h"
75 #include "yamf/model/command/additemfilter.h"
76 #include "model/command/addtweening.h"
78 #include "yamf/model/libraryitem.h"
79 #include "yamf/model/audiolayer.h"
81 #include "yamf/effect/factory.h"
82 #include "yamf/effect/filter.h"
84 #include <drawing/abstracttool.h>
85 #include <private/addsymboldialog.h>
93 #include <QGLFramebufferObject>
95 class GLDevice
: public QGLWidget
98 GLDevice() : QGLWidget()
107 glDisable(GL_DEPTH_TEST
);
112 struct YAMF::Drawing::PaintArea::Private
114 Private(YAMF::Drawing::PaintArea
*paintArea
, Model::Project
*const project
) : paintArea(paintArea
), project(project
), lastScaleFactor(1.0)
118 DGui::CommandHistory
*history
;
120 YAMF::Drawing::PaintArea
*paintArea
;
127 YAMF::Drawing::Private::PaintAreaRotator
*rotator
;
128 Photogram
*photogram
;
130 struct FramePosition
{
136 struct ItemProperties
{
141 QList
<ItemProperties
> properties
;
145 DGui::ActionManager actionManager
;
147 Model::Project
*const project
;
149 double lastScaleFactor
;
151 QToolBar
*toolsConfigBar
;
152 QToolBar
*effectsConfigBar
;
157 * Construye un area de trabajo relacionada con el proyecto @p project.
159 PaintArea::PaintArea(Model::Project
*const project
, QWidget
* parent
) : QGraphicsView(parent
), d(new Private(this, project
) )
161 d
->history
= new DGui::CommandHistory( project
->commandManager()->stack(), this);
163 d
->photogram
= new Photogram(this);
168 d
->rotator
= new YAMF::Drawing::Private::PaintAreaRotator(this, this);
170 d
->drawingRect
= QRectF(QPointF(0,0), QSizeF( 500, 400 ) ); // FIXME: configurable
172 d
->photogram
->setSceneRect(d
->drawingRect
);
173 setScene(d
->photogram
);
177 setUseOpenGL( false );
178 setInteractive ( true );
182 setCurrentFrame(-1, -1, -1);
184 d
->origin
= mapToScene(QPoint(0, 0));
189 d
->toolsConfigBar
= new QToolBar(tr("Configure tool"), this);
191 d
->effectsConfigBar
= new QToolBar(tr("Configure effects"), this);
196 * Guarda en la configuracion el estado de las propiedades del area de dibujo.
198 void PaintArea::saveState()
200 DCore::Config
*config
= dApp
->config( "PaintArea" );
202 config
->setValue("render_hints", int(renderHints()));
203 config
->setValue("show_grid", d
->drawGrid
);
210 * Recupera de la configuracion el estado de las propiedades del area de dibujo.
212 void PaintArea::restoreState()
214 DCore::Config
*config
= dApp
->config( "PaintArea" );
216 int renderHints
= config
->value("render_hints", int(this->renderHints())).toInt();
217 setRenderHints(QPainter::RenderHints(renderHints
));
219 bool showGrid
= config
->value("show_grid", false).toBool();
220 setDrawGrid(showGrid
);
228 PaintArea::~PaintArea()
232 d
->toolsConfigBar
->clear();
233 d
->effectsConfigBar
->clear();
243 * Crea las acciones relacionadas con el area de dibujo.
245 void PaintArea::createActions()
247 addAction( d
->history
->undoAction() );
248 addAction( d
->history
->redoAction() );
250 connect(d
->project
->commandManager(), SIGNAL(historyChanged()), this, SLOT(onHistoryChanged()));
252 QAction
*remove
= new QAction(DGui::IconLoader::self()->load("edit-delete.svg"), tr("Delete"), this);
253 remove
->setShortcut(QKeySequence::Delete
);
254 connect(remove
, SIGNAL(triggered()), this, SLOT(removeSelectedObjects()));
257 QAction
*selectAll
= new QAction(DGui::IconLoader::self()->load("select-all.svg"), tr("Select all"), this);
258 selectAll
->setShortcut(QKeySequence::SelectAll
);
259 connect(selectAll
, SIGNAL(triggered()), this, SLOT(selectAllObjects()));
260 addAction(selectAll
);
262 QAction
*copy
= new QAction( DGui::IconLoader::self()->load("edit-copy.svg"), tr("Copy"), this);
263 copy
->setShortcut(QKeySequence::Copy
);
264 connect(copy
, SIGNAL(triggered()), this, SLOT(copySelectedObjects()));
267 QAction
*paste
= new QAction(DGui::IconLoader::self()->load("edit-paste.svg"), tr("Paste"), this);
268 paste
->setShortcut(QKeySequence::Paste
);
269 connect(paste
, SIGNAL(triggered()), this, SLOT(pasteObjects()));
272 QAction
*cut
= new QAction(DGui::IconLoader::self()->load("edit-cut.svg"), tr("Cut"), this);
273 cut
->setShortcut(QKeySequence::Cut
);
274 connect(cut
, SIGNAL(triggered()), this, SLOT(cutSelectedObjects()));
278 d
->actionManager
.add(selectAll
, "selectall", "edit");
279 d
->actionManager
.addSeparator("edit");
280 d
->actionManager
.add(cut
, "cut", "edit");
281 d
->actionManager
.add(copy
, "copy", "edit");
282 d
->actionManager
.add(paste
, "paste", "edit");
283 d
->actionManager
.addSeparator("edit");
284 d
->actionManager
.add(remove
, "remove", "edit");
288 QAction
*group
= new QAction(DGui::IconLoader::self()->load("object-group.svg"), tr("Group"), this);
289 group
->setShortcut(Qt::CTRL
+ Qt::Key_G
);
290 connect(group
, SIGNAL(triggered()), this, SLOT(groupSelectedObjects()));
291 d
->actionManager
.add(group
, "group", "object");
294 QAction
*ungroup
= new QAction(DGui::IconLoader::self()->load("object-ungroup.svg"), tr("Ungroup"), this);
295 ungroup
->setShortcut(Qt::CTRL
+ Qt::SHIFT
+ Qt::Key_G
);
296 connect(ungroup
, SIGNAL(triggered()), this, SLOT(ungroupSelectedObject()));
297 d
->actionManager
.add(ungroup
, "ungroup", "object");
300 QAction
*sendToBack
= new QAction(DGui::IconLoader::self()->load("object-send-to-back.svg"), tr("Send to back"), this);
301 sendToBack
->setShortcut(Qt::Key_Home
);
302 connect(sendToBack
, SIGNAL(triggered()), this, SLOT(sendToBackSelectedObjects()));
303 d
->actionManager
.add(sendToBack
, "sendtoback", "object-order");
304 addAction(sendToBack
);
306 QAction
*bringToFront
= new QAction(DGui::IconLoader::self()->load("object-bring-to-front.svg"), tr("Bring to front"), this);
307 bringToFront
->setShortcut(Qt::Key_End
);
308 connect(bringToFront
, SIGNAL(triggered()), this, SLOT(bringToFrontSelectedObjects()));
309 d
->actionManager
.add(bringToFront
, "bringtofront", "object-order");
310 addAction(bringToFront
);
312 QAction
*sendBackwards
= new QAction(DGui::IconLoader::self()->load("object-send-backwards.svg"), tr("Send backwards"), this);
313 sendBackwards
->setShortcut(Qt::Key_PageDown
);
314 connect(sendBackwards
, SIGNAL(triggered()), this, SLOT(sendBackwardsSelectedObjects()));
315 d
->actionManager
.add(sendBackwards
, "sendbackwards", "object-order");
316 addAction(sendBackwards
);
318 QAction
*bringForwards
= new QAction(DGui::IconLoader::self()->load("object-bring-forwards.svg"), tr("Bring forwards"), this);
319 bringForwards
->setShortcut(Qt::Key_PageUp
);
320 connect(bringForwards
, SIGNAL(triggered()), this, SLOT(bringForwardsSelectedObjects()));
321 d
->actionManager
.add(bringForwards
, "bringforwards", "object-order");
322 addAction(bringForwards
);
326 QAction
*addToLibrary
= new QAction(DGui::IconLoader::self()->load("object-bring-forwards.svg"), tr("Add to library..."), this);
327 connect(addToLibrary
, SIGNAL(triggered()), this, SLOT(addToLibrary()));
328 d
->actionManager
.add(addToLibrary
, "addtolibrary", "library");
329 addAction(addToLibrary
);
331 QAction
*applySymbol
= new QAction(DGui::IconLoader::self()->load(""), tr("Apply to symbol..."), this);
332 connect(applySymbol
, SIGNAL(triggered()), this, SLOT(applyCurrentSymbol()));
333 d
->actionManager
.add(applySymbol
, "applysymbol", "library");
339 * Si @p use es verdadero permite que la animación se vea con antialiasing y si es false desactiva el antialiasing.
341 void PaintArea::setAntialiasing(bool use
)
344 if ( QGLWidget
*gl
= dynamic_cast<QGLWidget
*>(viewport() ) )
346 gl
->setUpdatesEnabled(false); // works better
347 gl
->setFormat(QGLFormat(QGL::SampleBuffers
| QGL::HasOverlay
/*| QGL::DirectRendering | QGL::AccumBuffer | QGL::Rgba */));
348 gl
->setUpdatesEnabled(true);
352 setRenderHint(QPainter::Antialiasing
, use
);
353 setRenderHint(QPainter::TextAntialiasing
, use
);
358 * Si @p opengl es verdadero activa el uso de openGl para dibujar el fotograma.
360 void PaintArea::setUseOpenGL(bool opengl
)
362 D_FUNCINFO
<< opengl
;
364 QCursor
cursor(Qt::ArrowCursor
);
367 cursor
= viewport()->cursor();
373 setViewport(new GLDevice());
377 // setViewport( new KTImageDevice() );
381 dWarning() << tr("OpenGL isn't supported");
384 // to restore the cursor.
387 viewport()->setCursor(cursor
);
388 viewport()->setAcceptDrops(true);
394 * Si @p draw es verdadero activa el dibujo de una grilla guia en el area, y si es falso la desactiva.
395 * Por defecto no se dibuja la grilla.
397 void PaintArea::setDrawGrid(bool draw
)
400 // resetCachedContent();
401 viewport()->update();
406 * Se asigna la herramienta @p tool como la herramienta actual.
408 void PaintArea::setTool(AbstractTool
*tool
)
410 if ( !scene() ) return;
412 QCursor cursor
= tool
->action()->cursor();
413 if( (!cursor
.pixmap().isNull() && cursor
.mask() != 0 && cursor
.shape() == Qt::BitmapCursor
&& cursor
.bitmap() != 0 ) || cursor
.shape() != Qt::BitmapCursor
)
414 viewport()->setCursor(cursor
);
416 d
->toolsConfigBar
->clear();
417 tool
->setupConfigBar(d
->toolsConfigBar
);
418 tool
->setPaintArea(this);
420 d
->photogram
->setTool(tool
);
425 * Retorna si esta activo el dibujo de la grilla.
427 bool PaintArea::drawGrid() const
432 void PaintArea::mousePressEvent( QMouseEvent
* event
)
434 if ( !canPaint() ) return;
436 QGraphicsItem
*item
= d
->photogram
->itemAt( mapToScene(event
->pos()) );
438 d
->effectsConfigBar
->clear();
441 if( YAMF::Effect::Filter
*filter
= dynamic_cast<YAMF::Effect::Filter
*>(item
) )
443 filter
->setupConfigBar(d
->effectsConfigBar
);
447 if ( event
->buttons() == Qt::RightButton
)
450 QMenu
*menu
= this->createMenu();
456 QMenu
*effects
= menu
->addMenu(tr("Effects"));
458 QAction
*blur
= effects
->addAction(tr("Blur"));
459 blur
->setData("blur");
461 QAction
*swirl
= effects
->addAction(tr("Swirl"));
462 swirl
->setData("swirl");
464 connect(effects
, SIGNAL(triggered(QAction
*)), this, SLOT(applyFilter(QAction
*)));
467 item
->setFlag(QGraphicsItem::ItemIsSelectable
, true);
468 item
->setSelected(true);
471 menu
->addSeparator();
473 if( qgraphicsitem_cast
<Model::LibraryItem
*>(item
) )
475 menu
->addAction(d
->actionManager
.find("applysymbol", "library"));
479 menu
->addAction(d
->actionManager
.find("addtolibrary", "library"));
482 menu
->addSeparator();
486 menu
->exec(event
->globalPos());
492 d
->photogram
->aboutToMousePress();
493 QGraphicsView::mousePressEvent(event
);
496 foreach(QGraphicsItem
*item
, d
->photogram
->selectedItems() )
498 if( item
->flags() & QGraphicsItem::ItemIsMovable
)
500 Private::ItemProperties prop
;
504 doc
.appendChild(Item::Serializer::properties(item
, doc
));
506 prop
.properties
= doc
.toString();
507 d
->properties
<< prop
;
512 void PaintArea::mouseMoveEvent( QMouseEvent
* event
)
514 if ( !canPaint()) return;
517 if( !d
->photogram
->isDrawing() && event
->buttons() == Qt::LeftButton
&& (event
->modifiers () == (Qt::ShiftModifier
| Qt::ControlModifier
)))
519 setUpdatesEnabled(false);
521 QGraphicsView::DragMode dragMode
= this->dragMode();
522 setDragMode(QGraphicsView::NoDrag
);
524 QPointF p1
= event
->pos();
525 QPointF p2
= d
->drawingRect
.center();
527 d
->rotator
->rotateTo( (int)(-(180*DGraphics::Algorithm::angleForPos(p1
,p2
))/M_PI
) );
529 setDragMode(dragMode
);
531 setUpdatesEnabled(true);
535 QGraphicsView::mouseMoveEvent(event
);
537 if( !d
->photogram
->mouseGrabberItem() && d
->photogram
->isDrawing() ) // HACK
539 QGraphicsSceneMouseEvent
mouseEvent(QEvent::GraphicsSceneMouseMove
);
540 mouseEvent
.setWidget(viewport());
542 mouseEvent
.setPos( event
->pos() );
543 mouseEvent
.setScenePos(mapToScene(event
->pos()));
545 mouseEvent
.setScreenPos(event
->globalPos());
546 mouseEvent
.setButtons(event
->buttons());
547 mouseEvent
.setButton(event
->button());
548 mouseEvent
.setModifiers(event
->modifiers());
549 mouseEvent
.setAccepted(false);
550 d
->photogram
->mouseMoved(&mouseEvent
);
554 emit
cursorMoved( mapToScene( event
->pos() ) );
557 void PaintArea::mouseReleaseEvent(QMouseEvent
*event
)
559 QGraphicsView::mouseReleaseEvent(event
);
561 if( ! d
->photogram
->mouseGrabberItem() && d
->photogram
->isDrawing() ) // HACK
563 QGraphicsSceneMouseEvent
mouseEvent(QEvent::GraphicsSceneMouseRelease
);
564 mouseEvent
.setWidget(viewport());
565 mouseEvent
.setPos( event
->pos() );
566 mouseEvent
.setScenePos(mapToScene(event
->pos()));
567 mouseEvent
.setScreenPos(event
->globalPos());
568 mouseEvent
.setButtons(event
->buttons());
569 mouseEvent
.setButton(event
->button());
570 mouseEvent
.setModifiers(event
->modifiers());
571 mouseEvent
.setAccepted(false);
572 // QApplication::sendEvent(d->photogram, &mouseEvent);
573 d
->photogram
->mouseReleased(&mouseEvent
);
576 foreach(Private::ItemProperties prop
, d
->properties
)
578 if(currentFrame()->visualIndexOf(prop
.item
) > -1 /*|| ritem == prop.item*/)
581 doc
.appendChild(Item::Serializer::properties(prop
.item
, doc
));
583 if( doc
.toString() != prop
.properties
)
585 Command::ModifyItem
*current
= new Command::ModifyItem( prop
.item
, prop
.properties
, currentFrame() );
586 addCommand( current
);
591 d
->properties
.clear();
596 void PaintArea::tabletEvent( QTabletEvent
* event
)
598 QGraphicsView::tabletEvent(event
);
602 * Función reimplementada para dibujar el fondo del area de dibujo, mostrando el area que va a aparecer en la animación y la grilla si esta activa la opción.
604 void PaintArea::drawBackground(QPainter
*painter
, const QRectF
&rect
)
606 QGraphicsView::drawBackground(painter
, rect
);
608 if( ! currentFrame() ) return;
612 bool hasAntialiasing
= painter
->renderHints() & QPainter::Antialiasing
;
614 painter
->setRenderHint(QPainter::Antialiasing
, false);
616 painter
->setPen( QPen(QColor(0,0,0,180), 3) );
618 painter
->fillRect( d
->drawingRect
, Qt::white
);
619 painter
->drawRect( d
->drawingRect
);
621 QPointF origin
= painter
->matrix().map(QPoint(0, 0));
623 if( origin
!= d
->origin
)
626 emit
originChanged( d
->origin
);
631 int sx
= (int)painter
->matrix().m11();
632 int sy
= (int)painter
->matrix().m22();
634 painter
->resetMatrix();
635 painter
->scale(sx
, sy
);
636 painter
->setPen( QPen(QColor(0,0,180, 50), 1) );
638 for(int i
= 0; i
< qMax(width(), height()); i
+= 10 )
640 painter
->drawLine(i
, 0, i
, height() );
641 painter
->drawLine(0, i
, width(), i
);
645 painter
->setRenderHint(QPainter::Antialiasing
, hasAntialiasing
);
653 * Función reimplementada para mostrar si el frame actual esta bloqueado.
655 void PaintArea::drawForeground( QPainter
*painter
, const QRectF
&rect
)
657 if ( Model::Frame
*frame
= currentFrame() )
659 if ( frame
->isLocked() )
661 painter
->fillRect(rect
, QColor(201,201,201, 200));
663 painter
->setFont(QFont("Arial", 30) );
664 QFontMetricsF
fm(painter
->font());
665 QString text
= tr("Locked");
667 painter
->drawText(QPointF(d
->photogram
->sceneRect().topRight().x() - fm
.width(text
), (d
->photogram
->sceneRect().topRight().y() + fm
.height()) / 2), text
);
674 * Retorna verdadero si se puede dibujar sobre el area de dibujo y falso si no.
676 bool PaintArea::canPaint() const
680 Model::Frame
*frame
= currentFrame();
684 return !frame
->isLocked() && !frame
->layer()->isLocked();
693 * Centra la vista del fotograma.
695 void PaintArea::centerDrawingArea()
697 centerOn(d
->drawingRect
.center());
703 void PaintArea::onHistoryChanged()
706 if( Model::Scene
*scene
= d
->photogram
->scene() )
708 if( scene
->logicalIndex() < 0 )
709 d
->photogram
->setCurrentScene(0);
712 d
->photogram
->drawCurrentPhotogram();
713 viewport()->update();
719 void PaintArea::applyFilter(QAction
*act
)
721 QList
<QGraphicsItem
*> selected
= d
->photogram
->selectedItems();
723 if( selected
.isEmpty() ) return;
725 QGraphicsItem
*item
= selected
.first();
726 QString filter
= act
->data().toString();
727 Model::Frame
*frame
= currentFrame();
729 if( frame
&& item
&& !filter
.isEmpty())
731 Model::Object
*object
= frame
->graphic(frame
->visualIndexOf(item
));
735 YAMF::Effect::Filter
*effect
= YAMF::Effect::Factory::create(filter
);
737 d
->effectsConfigBar
->clear();
738 effect
->setupConfigBar(d
->effectsConfigBar
);
741 YAMF::Command::AddItemFilter
*cmd
= new YAMF::Command::AddItemFilter(object
, effect
);
747 void PaintArea::wheelEvent(QWheelEvent
*event
)
749 if(event
->modifiers () == Qt::ControlModifier
)
751 scaleView(pow(( double)2, -event
->delta() / 240.0));
755 QGraphicsView::wheelEvent(event
);
759 bool PaintArea::viewportEvent(QEvent
*e
)
761 bool ret
= QGraphicsView::viewportEvent(e
);
763 if( e
->type() == QEvent::Show
)
765 if( d
->photogram
->items().isEmpty() )
767 d
->photogram
->drawCurrentPhotogram();
776 * Escala la vista sobre el fotograma en un factor @p scaleFactor.
778 void PaintArea::scaleView(double scaleFactor
)
780 qreal factor
= matrix().scale(scaleFactor
, scaleFactor
).mapRect(QRectF(0, 0, 1, 1)).width();
781 if (factor
< 0.07 || factor
> 100)
785 d
->lastScaleFactor
*= scaleFactor
;
786 scale(scaleFactor
, scaleFactor
);
788 emit
scaled(d
->lastScaleFactor
);
793 * Hace aumento sobre el fotograma actual en un porcentaje @p percent.
795 void PaintArea::setZoom(int percent
)
797 double factor
= (double)percent
/ 100.0;
799 if( factor
== d
->lastScaleFactor
) return;
801 double restoreFactor
= 1.0/d
->lastScaleFactor
;
803 scale(restoreFactor
, restoreFactor
);
805 d
->lastScaleFactor
= factor
;
807 scale(factor
, factor
);
814 * Rota la vista sobre el fotograma.
816 void PaintArea::setRotationAngle(int angle
)
818 rotate(angle
- d
->angle
);
824 * Retorna el manejador de brochas del area de dibujo.
826 BrushManager
*PaintArea::brushManager() const
828 return d
->photogram
->brushManager();
833 * Retorna el area en la cual va aparecer en la animación.
835 QRectF
PaintArea::drawingRect() const
837 return d
->drawingRect
;
842 * Retorna el fotograma actual.
844 Photogram
*PaintArea::photogram() const
851 * Cambia el frame actual.
853 void PaintArea::setCurrentFrame(int sceneIndex
, int layerIndex
, int frameIndex
)
855 // dfDebug << "scene = " << sceneIndex << " layer = " << layerIndex << "frame = " << frameIndex;
856 Model::Scene
*scene
= d
->project
->scene(sceneIndex
);
860 d
->photogram
->setCurrentScene(scene
);
861 d
->photogram
->setCurrent(frameIndex
);
862 d
->framePosition
.layer
= layerIndex
;
863 d
->framePosition
.frame
= frameIndex
;
865 d
->photogram
->drawCurrentPhotogram();
866 viewport()->update();
871 * Retorna el proyecto asociado al area de dibujo.
873 Model::Project
*PaintArea::project() const
880 * Retorna la escena actual.
882 Model::Scene
*PaintArea::currentScene() const
884 return d
->photogram
->scene();
889 * Retorna la capa actual.
891 Model::Layer
*PaintArea::currentLayer() const
893 Model::Scene
*scene
= d
->photogram
->scene();
897 return scene
->layer(d
->framePosition
.layer
);
906 * Retorna el frame actual.
908 Model::Frame
*PaintArea::currentFrame() const
910 Model::Layer
*layer
= currentLayer();
914 return layer
->frame(d
->framePosition
.frame
);
925 void PaintArea::addCommand(Command::Base
*command
)
927 d
->project
->commandManager()->addCommand(command
);
932 * Retorna la historia de comandos
935 DGui::CommandHistory
*PaintArea::history() const
942 * Retorna la acción que permite remover los elementos seleccionados en el area.
945 QAction
*PaintArea::removeAction()
947 return d
->actionManager
.find("remove", "edit");
952 * Retorna la acción que permite agrupar los elementos seleccionados en el area.
955 QAction
*PaintArea::groupAction()
957 return d
->actionManager
.find("group", "object");
962 * Retorna la acción que permite des-agrupar los elementos seleccionados en el area.
965 QAction
*PaintArea::ungroupAction()
967 return d
->actionManager
.find("ungroup", "object");
972 * Retorna la acción que permite enviar al fondo los elementos seleccionados en el area.
975 QAction
*PaintArea::sendToBackAction()
977 return d
->actionManager
.find( "sendtoback", "object-order");
982 * Retorna la acción que permite enviar al frente los elementos seleccionados en el area.
985 QAction
*PaintArea::bringToFrontAction()
987 return d
->actionManager
.find( "bringtofront", "object-order");
993 * Retorna la acción que permite enviar hacia atras una unidad los elementos seleccionados en el area.
996 QAction
*PaintArea::sendBackwardsAction()
998 return d
->actionManager
.find( "sendbackwards", "object-order");
1003 * Retorna la acción que permite enviar hacia adelante una unidad los elementos seleccionados en el area.
1005 QAction
*PaintArea::bringForwardsAction()
1007 return d
->actionManager
.find( "bringforwards", "object-order");
1012 * Retorna la acción que permite copiar los elementos seleccionados en el area.
1014 QAction
*PaintArea::copyAction()
1016 return d
->actionManager
.find( "copy", "edit");
1021 * Retorna la acción que permite pegar los elementos que estan en el portapapeles en el area.
1023 QAction
*PaintArea::pasteAction()
1025 return d
->actionManager
.find( "paste", "edit");
1030 * Retorna la acción que permite cortar los elementos seleccionados en el area.
1032 QAction
*PaintArea::cutAction()
1034 return d
->actionManager
.find( "cut", "edit");
1039 * Retorna la acción que permite seleccionar todos los elementos en el area.
1041 QAction
*PaintArea::selectAllAction()
1043 return d
->actionManager
.find("selectall", "edit");
1048 * Crea el menu contextual de el area de dibujo.
1050 QMenu
*PaintArea::createMenu()
1052 QMenu
*menu
= new QMenu(tr("Drawing area"), this);
1054 Command::Manager
*manager
= d
->project
->commandManager();
1056 menu
->addAction(d
->history
->undoAction()->icon(), d
->history
->undoAction()->text(), d
->history
, SLOT(undo()))->setEnabled(d
->history
->undoAction()->isEnabled());
1057 menu
->addAction(d
->history
->redoAction()->icon(), d
->history
->redoAction()->text(), d
->history
, SLOT(redo()))->setEnabled(d
->history
->redoAction()->isEnabled());
1059 menu
->addSeparator();
1060 d
->actionManager
.setupMenu(menu
, "edit", false);
1061 menu
->addSeparator();
1063 QMenu
*order
= new QMenu(tr("Order"));
1064 d
->actionManager
.setupMenu(order
, "object-order");
1066 menu
->addMenu (order
);
1067 menu
->addSeparator();
1069 if ( AbstractTool
*tool
= d
->photogram
->currentTool() )
1071 if( QMenu
*toolMenu
= tool
->menu() )
1073 menu
->addSeparator();
1074 menu
->addMenu(toolMenu
);
1083 * Retorna la barra de herramientas que provee la interfaz grafica para la configuración de las herramientas.
1085 QToolBar
*PaintArea::toolsConfigBar() const
1087 return d
->toolsConfigBar
;
1092 * Retorna la barra de herramientas que provee la interfaz grafica para la configuración de los efectos.
1094 QToolBar
*PaintArea::effectsConfigBar() const
1096 return d
->effectsConfigBar
;
1099 void PaintArea::checkActions()
1101 if(! scene()->selectedItems().isEmpty())
1103 d
->actionManager
.setEnabled("object-order", true);
1104 d
->actionManager
.find("remove", "edit")->setEnabled(true);
1105 d
->actionManager
.find("cut", "edit")->setEnabled(true);
1106 d
->actionManager
.find("copy", "edit")->setEnabled(true);
1107 d
->actionManager
.find("addtolibrary", "library")->setEnabled(true);
1111 d
->actionManager
.setEnabled("object-order", false);
1112 d
->actionManager
.find("remove", "edit")->setEnabled(false);
1113 d
->actionManager
.find("cut", "edit")->setEnabled(false);
1114 d
->actionManager
.find("copy", "edit")->setEnabled(false);
1115 d
->actionManager
.find("addtolibrary", "library")->setEnabled(false);
1118 QString xml
= QApplication::clipboard()->mimeData()->data("yamf-graphics");
1119 if ( !xml
.isEmpty() )
1121 d
->actionManager
.find("paste", "edit")->setEnabled(true);
1125 d
->actionManager
.find("paste", "edit")->setEnabled(false);
1131 * Remueve los elementos seleccionados.
1133 void PaintArea::removeSelectedObjects()
1135 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1136 if( items
.count() > 0 )
1138 currentFrame()->removeItems(items
);
1139 this->checkActions();
1146 * Agrupa los elementos seleccionados.
1148 void PaintArea::groupSelectedObjects()
1150 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1151 if( items
.count() > 0 )
1153 addCommand(new Command::GroupItem(items
, currentFrame()));
1159 * Desagrupa los elementos seleccionados.
1161 void PaintArea::ungroupSelectedObject()
1163 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1164 QList
<Item::Group
*> groups
;
1166 Model::Frame
*frame
= currentFrame();
1168 foreach(QGraphicsItem
*item
, items
)
1170 if( Item::Group
*group
= qgraphicsitem_cast
<Item::Group
*>(item
) )
1172 addCommand(new Command::UngroupItem(group
, currentFrame()));
1179 * Envia atras los elementos seleccionados.
1181 void PaintArea::sendToBackSelectedObjects()
1183 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1185 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1187 Model::Frame
*frame
= currentFrame();
1188 foreach(QGraphicsItem
*item
, items
)
1190 Model::Object
*o
= frame
->graphic(item
);
1193 addCommand(new Command::SendToBackItem(o
));
1200 * Trae adelante los elementos seleccionados.
1202 void PaintArea::bringToFrontSelectedObjects()
1204 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1206 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1208 QList
<QGraphicsItem
*>::iterator it
= items
.end();
1210 Model::Frame
*frame
= currentFrame();
1212 while(it
!= items
.begin())
1215 Model::Object
*o
= frame
->graphic(*it
);
1218 addCommand(new Command::BringToFrontItem(o
));
1225 * Envia atras una unidad los elementos seleccionados.
1227 void PaintArea::sendBackwardsSelectedObjects()
1229 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1231 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1233 Model::Frame
*frame
= currentFrame();
1234 foreach(QGraphicsItem
*item
, items
)
1236 Model::Object
*o
= frame
->graphic(item
);
1239 addCommand(new Command::SendBackwardsItem(o
));
1247 * Trae al frente una unidad los elementos seleccionados.
1249 void PaintArea::bringForwardsSelectedObjects()
1251 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1253 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1255 QList
<QGraphicsItem
*>::iterator it
= items
.end();
1257 Model::Frame
*frame
= currentFrame();
1259 while(it
!= items
.begin())
1262 Model::Object
*o
= frame
->graphic(*it
);
1265 addCommand(new Command::BringForwardsItem(o
));
1272 * Copia los elementos seleccionados.
1274 void PaintArea::copySelectedObjects()
1276 QList
<QGraphicsItem
*> selecteds
= scene()->selectedItems();
1279 QDomElement root
= orig
.createElement("yamf-graphics");
1281 foreach(QGraphicsItem
*item
, selecteds
)
1283 int index
= currentFrame()->visualIndexOf( item
);
1287 Model::Object
*graphic
= currentFrame()->graphic(index
);
1288 root
.appendChild(graphic
->toXml( orig
));
1292 orig
.appendChild(root
);
1294 QMimeData
*mimeData
= new QMimeData
;
1296 mimeData
->setData("yamf-graphics", orig
.toString().toLocal8Bit());
1297 //TODO: image/svg+xml
1298 QApplication::clipboard()->setMimeData( mimeData
);
1303 * Pega los elementos en el portapapeles.
1305 void PaintArea::pasteObjects()
1307 if( !currentFrame() ) return;
1309 const QMimeData
*mimeData
= QApplication::clipboard()->mimeData();
1311 QString xml
= mimeData
->data("yamf-graphics");
1314 if(!doc
.setContent(xml
))
1319 // TODO: image/svg+xml
1321 QDomElement docElem
= doc
.documentElement();
1322 QDomNode n
= docElem
.firstChild();
1326 QDomElement e
= n
.toElement();
1330 QTextStream
ts(&xml
);
1333 Model::Object
*object
= new Model::Object(currentFrame());
1334 object
->fromXml(xml
);
1336 currentFrame()->addObject(object
);
1338 n
= n
.nextSibling();
1340 d
->photogram
->drawCurrentPhotogram();
1345 * Corta los elementos seleccionados.
1347 void PaintArea::cutSelectedObjects()
1349 copySelectedObjects();
1350 removeSelectedObjects();
1355 * Selecciona todos los elementos en el area.
1357 void PaintArea::selectAllObjects()
1359 foreach(QGraphicsItem
*item
, photogram()->items() )
1361 item
->setFlag(QGraphicsItem::ItemIsSelectable
);
1362 item
->setSelected(true);
1368 * Añade lso elementos seleccionados a la biblioteca de objetos.
1370 void PaintArea::addToLibrary()
1372 QList
<QGraphicsItem
*> selecteds
= scene()->selectedItems();
1374 if ( selecteds
.isEmpty() )
1376 DGui::Osd::self()->display(tr("No items selected"), DGui::Osd::Error
);
1380 YAMF::Drawing::Private::AddSymbolDialog addSymbolDialog
;
1382 YAMF::Model::Library
*library
= d
->project
->library();
1384 QList
<QGraphicsItem
*> symbols
;
1386 foreach(QGraphicsItem
*item
, selecteds
)
1388 if( YAMF::Common::AbstractSerializable
*serializable
= dynamic_cast<YAMF::Common::AbstractSerializable
*>(item
) )
1390 addSymbolDialog
.addSymbol(item
);
1394 if( addSymbolDialog
.exec() == QDialog::Accepted
)
1396 for(int i
= 0; i
< addSymbolDialog
.symbolCount(); i
++)
1398 library
->addItemSymbol(addSymbolDialog
.symbol(i
), addSymbolDialog
.symbolName(i
));
1403 void PaintArea::applyCurrentSymbol()
1405 if( d
->photogram
->selectedItems().count() > 0 )
1407 if( Model::LibraryItem
*libraryItem
= qgraphicsitem_cast
<Model::LibraryItem
*>( d
->photogram
->selectedItems().first()) )
1409 YAMF::Command::ModifySymbol
*cmd
= new YAMF::Command::ModifySymbol(libraryItem
);
1418 * Añade un simbolo de la biblioteca identificado con @p id a el area .
1420 void PaintArea::addSymbol(const QString
&id
)
1422 YAMF::Model::LibraryObject
*object
= d
->project
->library()->findObject(id
);
1431 * Añade un simbolo @p object de la biblioteca a el area .
1433 void PaintArea::addSymbol(YAMF::Model::LibraryObject
*object
)
1435 YAMF::Model::Frame
*frame
= currentFrame();
1436 YAMF::Model::Scene
*scene
= currentScene();
1438 switch(object
->type())
1440 case YAMF::Model::LibraryObject::Sound
:
1442 Model::LibrarySoundObject
*soundObject
= dynamic_cast<Model::LibrarySoundObject
*>(object
);
1445 YAMF::Model::AudioLayer
*layer
= scene
->createAudioLayer();
1446 layer
->fromSymbol(soundObject
);
1450 case YAMF::Model::LibraryObject::Svg
:
1451 case YAMF::Model::LibraryObject::Item
:
1452 case YAMF::Model::LibraryObject::Image
:
1453 case YAMF::Model::LibraryObject::Text
:
1457 YAMF::Model::LibraryItem
*item
= new YAMF::Model::LibraryItem(object
);
1458 frame
->addItem(item
);