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"
77 #include "yamf/model/libraryitem.h"
78 #include "yamf/model/audiolayer.h"
80 #include "yamf/effect/factory.h"
81 #include "yamf/effect/filter.h"
83 #include <drawing/abstracttool.h>
84 #include <private/addsymboldialog.h>
92 #include <QGLFramebufferObject>
94 class GLDevice
: public QGLWidget
97 GLDevice() : QGLWidget()
106 glDisable(GL_DEPTH_TEST
);
111 struct YAMF::Drawing::PaintArea::Private
113 Private(YAMF::Drawing::PaintArea
*paintArea
, Model::Project
*const project
) : paintArea(paintArea
), project(project
), lastScaleFactor(1.0)
117 YAMF::Drawing::PaintArea
*paintArea
;
124 YAMF::Drawing::Private::PaintAreaRotator
*rotator
;
125 Photogram
*photogram
;
127 struct FramePosition
{
133 struct ItemProperties
{
138 QList
<ItemProperties
> properties
;
142 DGui::ActionManager actionManager
;
144 Model::Project
*const project
;
146 double lastScaleFactor
;
148 QToolBar
*toolsConfigBar
;
149 QToolBar
*effectsConfigBar
;
153 Item::TweenerStep
*step
;
155 QList
<RecordStep
> steps
;
160 void PaintArea::Private::recordIt()
162 Model::Object
*recorded
= photogram
->recorded();
164 int currentPos
= paintArea
->currentFrame()->visualIndex();
165 int objectPos
= recorded
->frame()->visualIndex();
168 record
.step
= new Item::TweenerStep(currentPos
-objectPos
);
170 record
.step
->setPosition(recorded
->item()->pos());
179 * Construye un area de trabajo relacionada con el proyecto @p project.
181 PaintArea::PaintArea(Model::Project
*const project
, QWidget
* parent
) : QGraphicsView(parent
), d(new Private(this, project
) )
183 d
->photogram
= new Photogram(this);
188 d
->rotator
= new YAMF::Drawing::Private::PaintAreaRotator(this, this);
190 d
->drawingRect
= QRectF(QPointF(0,0), QSizeF( 500, 400 ) ); // FIXME: configurable
192 d
->photogram
->setSceneRect(d
->drawingRect
);
193 setScene(d
->photogram
);
197 setUseOpenGL( false );
198 setInteractive ( true );
202 setCurrentFrame(-1, -1, -1);
204 d
->origin
= mapToScene(QPoint(0, 0));
209 d
->toolsConfigBar
= new QToolBar(tr("Configure tool"), this);
211 d
->effectsConfigBar
= new QToolBar(tr("Configure effects"), this);
216 * Guarda en la configuracion el estado de las propiedades del area de dibujo.
218 void PaintArea::saveState()
220 DCore::Config
*config
= dApp
->config( "PaintArea" );
222 config
->setValue("render_hints", int(renderHints()));
223 config
->setValue("show_grid", d
->drawGrid
);
230 * Recupera de la configuracion el estado de las propiedades del area de dibujo.
232 void PaintArea::restoreState()
234 DCore::Config
*config
= dApp
->config( "PaintArea" );
236 int renderHints
= config
->value("render_hints", int(this->renderHints())).toInt();
237 setRenderHints(QPainter::RenderHints(renderHints
));
239 bool showGrid
= config
->value("show_grid", false).toBool();
240 setDrawGrid(showGrid
);
248 PaintArea::~PaintArea()
250 d
->toolsConfigBar
->clear();
258 * Crea las acciones relacionadas con el area de dibujo.
260 void PaintArea::createActions()
262 DGui::CommandHistory
*history
= d
->project
->commandManager()->history();
263 addAction( history
->undoAction() );
264 addAction( history
->redoAction() );
266 connect(d
->project
->commandManager(), SIGNAL(historyChanged()), this, SLOT(onHistoryChanged()));
268 QAction
*remove
= new QAction(DGui::IconLoader::self()->load("edit-delete.svg"), tr("Delete"), this);
269 remove
->setShortcut(QKeySequence::Delete
);
270 connect(remove
, SIGNAL(triggered()), this, SLOT(removeSelectedObjects()));
273 QAction
*selectAll
= new QAction(DGui::IconLoader::self()->load("select-all.svg"), tr("Select all"), this);
274 selectAll
->setShortcut(QKeySequence::SelectAll
);
275 connect(selectAll
, SIGNAL(triggered()), this, SLOT(selectAllObjects()));
276 addAction(selectAll
);
278 QAction
*copy
= new QAction( DGui::IconLoader::self()->load("edit-copy.svg"), tr("Copy"), this);
279 copy
->setShortcut(QKeySequence::Copy
);
280 connect(copy
, SIGNAL(triggered()), this, SLOT(copySelectedObjects()));
283 QAction
*paste
= new QAction(DGui::IconLoader::self()->load("edit-paste.svg"), tr("Paste"), this);
284 paste
->setShortcut(QKeySequence::Paste
);
285 connect(paste
, SIGNAL(triggered()), this, SLOT(pasteObjects()));
288 QAction
*cut
= new QAction(DGui::IconLoader::self()->load("edit-cut.svg"), tr("Cut"), this);
289 cut
->setShortcut(QKeySequence::Cut
);
290 connect(cut
, SIGNAL(triggered()), this, SLOT(cutSelectedObjects()));
294 d
->actionManager
.add(selectAll
, "selectall", "edit");
295 d
->actionManager
.addSeparator("edit");
296 d
->actionManager
.add(cut
, "cut", "edit");
297 d
->actionManager
.add(copy
, "copy", "edit");
298 d
->actionManager
.add(paste
, "paste", "edit");
299 d
->actionManager
.addSeparator("edit");
300 d
->actionManager
.add(remove
, "remove", "edit");
304 QAction
*group
= new QAction(DGui::IconLoader::self()->load("object-group.svg"), tr("Group"), this);
305 group
->setShortcut(Qt::CTRL
+ Qt::Key_G
);
306 connect(group
, SIGNAL(triggered()), this, SLOT(groupSelectedObjects()));
307 d
->actionManager
.add(group
, "group", "object");
310 QAction
*ungroup
= new QAction(DGui::IconLoader::self()->load("object-ungroup.svg"), tr("Ungroup"), this);
311 ungroup
->setShortcut(Qt::CTRL
+ Qt::SHIFT
+ Qt::Key_G
);
312 connect(ungroup
, SIGNAL(triggered()), this, SLOT(ungroupSelectedObject()));
313 d
->actionManager
.add(ungroup
, "ungroup", "object");
316 QAction
*sendToBack
= new QAction(DGui::IconLoader::self()->load("object-send-to-back.svg"), tr("Send to back"), this);
317 sendToBack
->setShortcut(Qt::Key_Home
);
318 connect(sendToBack
, SIGNAL(triggered()), this, SLOT(sendToBackSelectedObjects()));
319 d
->actionManager
.add(sendToBack
, "sendtoback", "object-order");
320 addAction(sendToBack
);
322 QAction
*bringToFront
= new QAction(DGui::IconLoader::self()->load("object-bring-to-front.svg"), tr("Bring to front"), this);
323 bringToFront
->setShortcut(Qt::Key_End
);
324 connect(bringToFront
, SIGNAL(triggered()), this, SLOT(bringToFrontSelectedObjects()));
325 d
->actionManager
.add(bringToFront
, "bringtofront", "object-order");
326 addAction(bringToFront
);
328 QAction
*sendBackwards
= new QAction(DGui::IconLoader::self()->load("object-send-backwards.svg"), tr("Send backwards"), this);
329 sendBackwards
->setShortcut(Qt::Key_PageDown
);
330 connect(sendBackwards
, SIGNAL(triggered()), this, SLOT(sendBackwardsSelectedObjects()));
331 d
->actionManager
.add(sendBackwards
, "sendbackwards", "object-order");
332 addAction(sendBackwards
);
334 QAction
*bringForwards
= new QAction(DGui::IconLoader::self()->load("object-bring-forwards.svg"), tr("Bring forwards"), this);
335 bringForwards
->setShortcut(Qt::Key_PageUp
);
336 connect(bringForwards
, SIGNAL(triggered()), this, SLOT(bringForwardsSelectedObjects()));
337 d
->actionManager
.add(bringForwards
, "bringforwards", "object-order");
338 addAction(bringForwards
);
342 QAction
*addToLibrary
= new QAction(DGui::IconLoader::self()->load("object-bring-forwards.svg"), tr("Add to library..."), this);
343 connect(addToLibrary
, SIGNAL(triggered()), this, SLOT(addToLibrary()));
344 d
->actionManager
.add(addToLibrary
, "addtolibrary", "library");
345 addAction(addToLibrary
);
347 QAction
*applySymbol
= new QAction(DGui::IconLoader::self()->load(""), tr("Apply to symbol..."), this);
348 connect(applySymbol
, SIGNAL(triggered()), this, SLOT(applyCurrentSymbol()));
349 d
->actionManager
.add(applySymbol
, "applysymbol", "library");
353 QAction
*recordItem
= new QAction(DGui::IconLoader::self()->load("media-record.svg"), tr("Record item"), this);
354 connect(recordItem
, SIGNAL(triggered()), this, SLOT(recordItem()));
355 d
->actionManager
.add(recordItem
, "recorditem", "item");
357 QAction
*stopRecordItem
= new QAction(DGui::IconLoader::self()->load("media-playback-stop.svg"), tr("Stop to record item"), this);
358 connect(stopRecordItem
, SIGNAL(triggered()), this, SLOT(stopRecordItem()));
359 d
->actionManager
.add(stopRecordItem
, "stoprecorditem", "item");
364 * Si @p use es verdadero permite que la animación se vea con antialiasing y si es false desactiva el antialiasing.
366 void PaintArea::setAntialiasing(bool use
)
369 if ( QGLWidget
*gl
= dynamic_cast<QGLWidget
*>(viewport() ) )
371 gl
->setUpdatesEnabled(false); // works better
372 gl
->setFormat(QGLFormat(QGL::SampleBuffers
| QGL::HasOverlay
/*| QGL::DirectRendering | QGL::AccumBuffer | QGL::Rgba */));
373 gl
->setUpdatesEnabled(true);
377 setRenderHint(QPainter::Antialiasing
, use
);
378 setRenderHint(QPainter::TextAntialiasing
, use
);
383 * Si @p opengl es verdadero activa el uso de openGl para dibujar el fotograma.
385 void PaintArea::setUseOpenGL(bool opengl
)
387 D_FUNCINFO
<< opengl
;
389 QCursor
cursor(Qt::ArrowCursor
);
392 cursor
= viewport()->cursor();
398 setViewport(new GLDevice());
402 // setViewport( new KTImageDevice() );
406 dWarning() << tr("OpenGL isn't supported");
409 // to restore the cursor.
412 viewport()->setCursor(cursor
);
413 viewport()->setAcceptDrops(true);
419 * Si @p draw es verdadero activa el dibujo de una grilla guia en el area, y si es falso la desactiva.
420 * Por defecto no se dibuja la grilla.
422 void PaintArea::setDrawGrid(bool draw
)
425 // resetCachedContent();
426 viewport()->update();
431 * Se asigna la herramienta @p tool como la herramienta actual.
433 void PaintArea::setTool(AbstractTool
*tool
)
435 if ( !scene() ) return;
437 QCursor cursor
= tool
->action()->cursor();
438 if( (!cursor
.pixmap().isNull() && cursor
.mask() != 0 && cursor
.shape() == Qt::BitmapCursor
&& cursor
.bitmap() != 0 ) || cursor
.shape() != Qt::BitmapCursor
)
439 viewport()->setCursor(cursor
);
441 d
->toolsConfigBar
->clear();
442 tool
->setupConfigBar(d
->toolsConfigBar
);
444 d
->photogram
->setTool(tool
);
449 * Retorna si esta activo el dibujo de la grilla.
451 bool PaintArea::drawGrid() const
456 void PaintArea::mousePressEvent( QMouseEvent
* event
)
458 if ( !canPaint() ) return;
460 QGraphicsItem
*item
= d
->photogram
->itemAt( mapToScene(event
->pos()) );
462 d
->effectsConfigBar
->clear();
465 if( YAMF::Effect::Filter
*filter
= dynamic_cast<YAMF::Effect::Filter
*>(item
) )
467 filter
->setupConfigBar(d
->effectsConfigBar
);
471 if ( event
->buttons() == Qt::RightButton
)
474 QMenu
*menu
= this->createMenu();
480 QMenu
*effects
= menu
->addMenu(tr("Effects"));
482 QAction
*blur
= effects
->addAction(tr("Blur"));
483 blur
->setData("blur");
485 QAction
*swirl
= effects
->addAction(tr("Swirl"));
486 swirl
->setData("swirl");
488 connect(effects
, SIGNAL(triggered(QAction
*)), this, SLOT(applyFilter(QAction
*)));
491 item
->setFlag(QGraphicsItem::ItemIsSelectable
, true);
492 item
->setSelected(true);
494 menu
->addAction(d
->actionManager
.find("recorditem", "item"));
497 if( d
->photogram
->recorded() )
499 menu
->addAction(d
->actionManager
.find("stoprecorditem", "item"));
502 menu
->addSeparator();
504 if( qgraphicsitem_cast
<Model::LibraryItem
*>(item
) )
506 menu
->addAction(d
->actionManager
.find("applysymbol", "library"));
510 menu
->addAction(d
->actionManager
.find("addtolibrary", "library"));
513 menu
->addSeparator();
517 menu
->exec(event
->globalPos());
523 d
->photogram
->aboutToMousePress();
524 QGraphicsView::mousePressEvent(event
);
527 foreach(QGraphicsItem
*item
, d
->photogram
->selectedItems() )
529 if( item
->flags() & QGraphicsItem::ItemIsMovable
)
531 Private::ItemProperties prop
;
535 doc
.appendChild(Item::Serializer::properties(item
, doc
));
537 prop
.properties
= doc
.toString();
538 d
->properties
<< prop
;
543 void PaintArea::mouseMoveEvent( QMouseEvent
* event
)
545 if ( !canPaint()) return;
548 if( !d
->photogram
->isDrawing() && event
->buttons() == Qt::LeftButton
&& (event
->modifiers () == (Qt::ShiftModifier
| Qt::ControlModifier
)))
550 setUpdatesEnabled(false);
552 QGraphicsView::DragMode dragMode
= this->dragMode();
553 setDragMode(QGraphicsView::NoDrag
);
555 QPointF p1
= event
->pos();
556 QPointF p2
= d
->drawingRect
.center();
558 d
->rotator
->rotateTo( (int)(-(180*DGraphics::Algorithm::angleForPos(p1
,p2
))/M_PI
) );
560 setDragMode(dragMode
);
562 setUpdatesEnabled(true);
566 QGraphicsView::mouseMoveEvent(event
);
568 if( !d
->photogram
->mouseGrabberItem() && d
->photogram
->isDrawing() ) // HACK
570 QGraphicsSceneMouseEvent
mouseEvent(QEvent::GraphicsSceneMouseMove
);
571 mouseEvent
.setWidget(viewport());
573 mouseEvent
.setPos( event
->pos() );
574 mouseEvent
.setScenePos(mapToScene(event
->pos()));
576 mouseEvent
.setScreenPos(event
->globalPos());
577 mouseEvent
.setButtons(event
->buttons());
578 mouseEvent
.setButton(event
->button());
579 mouseEvent
.setModifiers(event
->modifiers());
580 mouseEvent
.setAccepted(false);
581 d
->photogram
->mouseMoved(&mouseEvent
);
585 emit
cursorMoved( mapToScene( event
->pos() ) );
588 void PaintArea::mouseReleaseEvent(QMouseEvent
*event
)
590 QGraphicsView::mouseReleaseEvent(event
);
592 if( ! d
->photogram
->mouseGrabberItem() && d
->photogram
->isDrawing() ) // HACK
594 QGraphicsSceneMouseEvent
mouseEvent(QEvent::GraphicsSceneMouseRelease
);
595 mouseEvent
.setWidget(viewport());
596 mouseEvent
.setPos( event
->pos() );
597 mouseEvent
.setScenePos(mapToScene(event
->pos()));
598 mouseEvent
.setScreenPos(event
->globalPos());
599 mouseEvent
.setButtons(event
->buttons());
600 mouseEvent
.setButton(event
->button());
601 mouseEvent
.setModifiers(event
->modifiers());
602 mouseEvent
.setAccepted(false);
603 // QApplication::sendEvent(d->photogram, &mouseEvent);
604 d
->photogram
->mouseReleased(&mouseEvent
);
608 Model::Object
*recorded
= d
->photogram
->recorded();
609 QGraphicsItem
*ritem
= 0;
612 ritem
= recorded
->item();
615 foreach(Private::ItemProperties prop
, d
->properties
)
617 if(currentFrame()->logicalIndexOf(prop
.item
) > -1 || ritem
== prop
.item
)
620 doc
.appendChild(Item::Serializer::properties(prop
.item
, doc
));
623 if( prop
.item
== ritem
)
627 else if( doc
.toString() != prop
.properties
)
629 Command::ModifyItem
*current
= new Command::ModifyItem( prop
.item
, prop
.properties
, currentFrame() );
630 addCommand( current
);
635 d
->properties
.clear();
640 void PaintArea::tabletEvent( QTabletEvent
* event
)
642 QGraphicsView::tabletEvent(event
);
646 * 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.
648 void PaintArea::drawBackground(QPainter
*painter
, const QRectF
&rect
)
650 QGraphicsView::drawBackground(painter
, rect
);
652 if( ! currentFrame() ) return;
656 bool hasAntialiasing
= painter
->renderHints() & QPainter::Antialiasing
;
658 painter
->setRenderHint(QPainter::Antialiasing
, false);
660 painter
->setPen( QPen(QColor(0,0,0,180), 3) );
662 painter
->fillRect( d
->drawingRect
, Qt::white
);
663 painter
->drawRect( d
->drawingRect
);
665 QPointF origin
= painter
->matrix().map(QPoint(0, 0));
667 if( origin
!= d
->origin
)
670 emit
originChanged( d
->origin
);
675 int sx
= (int)painter
->matrix().m11();
676 int sy
= (int)painter
->matrix().m22();
678 painter
->resetMatrix();
679 painter
->scale(sx
, sy
);
680 painter
->setPen( QPen(QColor(0,0,180, 50), 1) );
682 for(int i
= 0; i
< qMax(width(), height()); i
+= 10 )
684 painter
->drawLine(i
, 0, i
, height() );
685 painter
->drawLine(0, i
, width(), i
);
689 painter
->setRenderHint(QPainter::Antialiasing
, hasAntialiasing
);
697 * Función reimplementada para mostrar si el frame actual esta bloqueado.
699 void PaintArea::drawForeground( QPainter
*painter
, const QRectF
&rect
)
701 if ( Model::Frame
*frame
= currentFrame() )
703 if ( frame
->isLocked() )
705 painter
->fillRect(rect
, QColor(201,201,201, 200));
707 painter
->setFont(QFont("Arial", 30) );
708 QFontMetricsF
fm(painter
->font());
709 QString text
= tr("Locked");
711 painter
->drawText(QPointF(d
->photogram
->sceneRect().topRight().x() - fm
.width(text
), (d
->photogram
->sceneRect().topRight().y() + fm
.height()) / 2), text
);
718 * Retorna verdadero si se puede dibujar sobre el area de dibujo y falso si no.
720 bool PaintArea::canPaint() const
724 Model::Frame
*frame
= currentFrame();
728 return !frame
->isLocked() && !frame
->layer()->isLocked();
737 * Centra la vista del fotograma.
739 void PaintArea::centerDrawingArea()
741 centerOn(d
->drawingRect
.center());
747 void PaintArea::onHistoryChanged()
749 if( Model::Scene
*scene
= d
->photogram
->scene() )
751 if( scene
->logicalIndex() < 0 )
752 d
->photogram
->setCurrentScene(0);
755 d
->photogram
->drawCurrentPhotogram();
756 viewport()->update();
762 void PaintArea::applyFilter(QAction
*act
)
764 QList
<QGraphicsItem
*> selected
= d
->photogram
->selectedItems();
766 if( selected
.isEmpty() ) return;
768 QGraphicsItem
*item
= selected
.first();
769 QString filter
= act
->data().toString();
770 Model::Frame
*frame
= currentFrame();
772 if( frame
&& item
&& !filter
.isEmpty())
774 Model::Object
*object
= frame
->graphic(frame
->logicalIndexOf(item
));
778 YAMF::Effect::Filter
*effect
= YAMF::Effect::Factory::create(filter
);
780 d
->effectsConfigBar
->clear();
781 effect
->setupConfigBar(d
->effectsConfigBar
);
784 YAMF::Command::AddItemFilter
*cmd
= new YAMF::Command::AddItemFilter(object
, effect
);
790 void PaintArea::wheelEvent(QWheelEvent
*event
)
792 if(event
->modifiers () == Qt::ControlModifier
)
794 scaleView(pow(( double)2, -event
->delta() / 240.0));
798 QGraphicsView::wheelEvent(event
);
802 bool PaintArea::viewportEvent(QEvent
*e
)
804 bool ret
= QGraphicsView::viewportEvent(e
);
806 if( e
->type() == QEvent::Show
)
808 if( d
->photogram
->items().isEmpty() )
810 d
->photogram
->drawCurrentPhotogram();
819 * Escala la vista sobre el fotograma en un factor @p scaleFactor.
821 void PaintArea::scaleView(double scaleFactor
)
823 qreal factor
= matrix().scale(scaleFactor
, scaleFactor
).mapRect(QRectF(0, 0, 1, 1)).width();
824 if (factor
< 0.07 || factor
> 100)
828 d
->lastScaleFactor
*= scaleFactor
;
829 scale(scaleFactor
, scaleFactor
);
831 emit
scaled(d
->lastScaleFactor
);
836 * Hace aumento sobre el fotograma actual en un porcentaje @p percent.
838 void PaintArea::setZoom(int percent
)
840 double factor
= (double)percent
/ 100.0;
842 if( factor
== d
->lastScaleFactor
) return;
844 double restoreFactor
= 1.0/d
->lastScaleFactor
;
846 if( d
->lastScaleFactor
> 1.0 )
848 scale(restoreFactor
, restoreFactor
);
850 else if ( d
->lastScaleFactor
< 1.0)
852 scale(restoreFactor
, restoreFactor
);
855 d
->lastScaleFactor
= factor
;
857 scale(factor
, factor
);
864 * Rota la vista sobre el fotograma.
866 void PaintArea::setRotationAngle(int angle
)
868 rotate(angle
- d
->angle
);
874 * Retorna el manejador de brochas del area de dibujo.
876 BrushManager
*PaintArea::brushManager() const
878 return d
->photogram
->brushManager();
883 * Retorna el area en la cual va aparecer en la animación.
885 QRectF
PaintArea::drawingRect() const
887 return d
->drawingRect
;
892 * Retorna el fotograma actual.
894 Photogram
*PaintArea::photogram() const
901 * Cambia el frame actual.
903 void PaintArea::setCurrentFrame(int sceneIndex
, int layerIndex
, int frameIndex
)
905 Model::Scene
*scene
= d
->project
->scene(sceneIndex
);
908 d
->photogram
->setCurrentScene(scene
);
909 d
->photogram
->setCurrent(frameIndex
);
910 d
->framePosition
.layer
= layerIndex
;
911 d
->framePosition
.frame
= frameIndex
;
913 d
->photogram
->drawCurrentPhotogram();
914 viewport()->update();
919 * Retorna el proyecto asociado al area de dibujo.
921 Model::Project
*PaintArea::project() const
928 * Retorna la escena actual.
930 Model::Scene
*PaintArea::currentScene() const
932 return d
->photogram
->scene();
937 * Retorna la capa actual.
939 Model::Layer
*PaintArea::currentLayer() const
941 Model::Scene
*scene
= d
->photogram
->scene();
945 return scene
->layer(d
->framePosition
.layer
);
954 * Retorna el frame actual.
956 Model::Frame
*PaintArea::currentFrame() const
958 Model::Layer
*layer
= currentLayer();
962 return layer
->frame(d
->framePosition
.frame
);
973 void PaintArea::addCommand(Command::Base
*command
)
975 d
->project
->commandManager()->addCommand(command
);
980 * Retorna la acción que permite remover los elementos seleccionados en el area.
983 QAction
*PaintArea::removeAction()
985 return d
->actionManager
.find("remove", "edit");
990 * Retorna la acción que permite agrupar los elementos seleccionados en el area.
993 QAction
*PaintArea::groupAction()
995 return d
->actionManager
.find("group", "object");
1000 * Retorna la acción que permite des-agrupar los elementos seleccionados en el area.
1003 QAction
*PaintArea::ungroupAction()
1005 return d
->actionManager
.find("ungroup", "object");
1010 * Retorna la acción que permite enviar al fondo los elementos seleccionados en el area.
1013 QAction
*PaintArea::sendToBackAction()
1015 return d
->actionManager
.find( "sendtoback", "object-order");
1020 * Retorna la acción que permite enviar al frente los elementos seleccionados en el area.
1023 QAction
*PaintArea::bringToFrontAction()
1025 return d
->actionManager
.find( "bringtofront", "object-order");
1031 * Retorna la acción que permite enviar hacia atras una unidad los elementos seleccionados en el area.
1034 QAction
*PaintArea::sendBackwardsAction()
1036 return d
->actionManager
.find( "sendbackwards", "object-order");
1041 * Retorna la acción que permite enviar hacia adelante una unidad los elementos seleccionados en el area.
1043 QAction
*PaintArea::bringForwardsAction()
1045 return d
->actionManager
.find( "bringforwards", "object-order");
1050 * Retorna la acción que permite copiar los elementos seleccionados en el area.
1052 QAction
*PaintArea::copyAction()
1054 return d
->actionManager
.find( "copy", "edit");
1059 * Retorna la acción que permite pegar los elementos que estan en el portapapeles en el area.
1061 QAction
*PaintArea::pasteAction()
1063 return d
->actionManager
.find( "paste", "edit");
1068 * Retorna la acción que permite cortar los elementos seleccionados en el area.
1070 QAction
*PaintArea::cutAction()
1072 return d
->actionManager
.find( "cut", "edit");
1077 * Retorna la acción que permite seleccionar todos los elementos en el area.
1079 QAction
*PaintArea::selectAllAction()
1081 return d
->actionManager
.find("selectall", "edit");
1086 * Crea el menu contextual de el area de dibujo.
1088 QMenu
*PaintArea::createMenu()
1090 QMenu
*menu
= new QMenu(tr("Drawing area"), this);
1092 Command::Manager
*manager
= d
->project
->commandManager();
1093 DGui::CommandHistory
*history
= manager
->history();
1095 menu
->addAction(history
->undoAction()->icon(), history
->undoAction()->text(), history
, SLOT(undo()))->setEnabled(history
->undoAction()->isEnabled());
1096 menu
->addAction(history
->redoAction()->icon(), history
->redoAction()->text(), history
, SLOT(redo()))->setEnabled(history
->redoAction()->isEnabled());
1098 menu
->addSeparator();
1099 d
->actionManager
.setupMenu(menu
, "edit", false);
1100 menu
->addSeparator();
1102 QMenu
*order
= new QMenu(tr("Order"));
1103 d
->actionManager
.setupMenu(order
, "object-order");
1105 menu
->addMenu (order
);
1106 menu
->addSeparator();
1108 if ( AbstractTool
*tool
= d
->photogram
->currentTool() )
1110 if( QMenu
*toolMenu
= tool
->menu() )
1112 menu
->addSeparator();
1113 menu
->addMenu(toolMenu
);
1122 * Retorna la barra de herramientas que provee la interfaz grafica para la configuración de las herramientas.
1124 QToolBar
*PaintArea::toolsConfigBar() const
1126 return d
->toolsConfigBar
;
1131 * Retorna la barra de herramientas que provee la interfaz grafica para la configuración de los efectos.
1133 QToolBar
*PaintArea::effectsConfigBar() const
1135 return d
->effectsConfigBar
;
1138 void PaintArea::checkActions()
1140 if(! scene()->selectedItems().isEmpty())
1142 d
->actionManager
.setEnabled("object-order", true);
1143 d
->actionManager
.find("remove", "edit")->setEnabled(true);
1144 d
->actionManager
.find("cut", "edit")->setEnabled(true);
1145 d
->actionManager
.find("copy", "edit")->setEnabled(true);
1146 d
->actionManager
.find("addtolibrary", "library")->setEnabled(true);
1150 d
->actionManager
.setEnabled("object-order", false);
1151 d
->actionManager
.find("remove", "edit")->setEnabled(false);
1152 d
->actionManager
.find("cut", "edit")->setEnabled(false);
1153 d
->actionManager
.find("copy", "edit")->setEnabled(false);
1154 d
->actionManager
.find("addtolibrary", "library")->setEnabled(false);
1157 QString xml
= QApplication::clipboard()->mimeData()->data("yamf-graphics");
1158 if ( !xml
.isEmpty() )
1160 d
->actionManager
.find("paste", "edit")->setEnabled(true);
1164 d
->actionManager
.find("paste", "edit")->setEnabled(false);
1170 * Remueve los elementos seleccionados.
1172 void PaintArea::removeSelectedObjects()
1174 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1175 if( items
.count() > 0 )
1177 currentFrame()->removeItems(items
);
1178 this->checkActions();
1185 * Agrupa los elementos seleccionados.
1187 void PaintArea::groupSelectedObjects()
1189 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1190 if( items
.count() > 0 )
1192 addCommand(new Command::GroupItem(items
, currentFrame()));
1198 * Desagrupa los elementos seleccionados.
1200 void PaintArea::ungroupSelectedObject()
1202 QList
<QGraphicsItem
*> items
= d
->photogram
->selectedItems();
1203 QList
<Item::Group
*> groups
;
1205 foreach(QGraphicsItem
*item
, items
)
1207 if( Item::Group
*group
= qgraphicsitem_cast
<Item::Group
*>(item
) )
1209 addCommand(new Command::UngroupItem(group
, currentFrame()));
1216 * Envia atras los elementos seleccionados.
1218 void PaintArea::sendToBackSelectedObjects()
1220 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1222 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1224 foreach(QGraphicsItem
*item
, items
)
1226 addCommand(new Command::SendToBackItem(item
));
1232 * Trae adelante los elementos seleccionados.
1234 void PaintArea::bringToFrontSelectedObjects()
1236 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1238 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1240 QList
<QGraphicsItem
*>::iterator it
= items
.end();
1242 while(it
!= items
.begin())
1245 addCommand(new Command::BringToFrontItem(*it
));
1251 * Envia atras una unidad los elementos seleccionados.
1253 void PaintArea::sendBackwardsSelectedObjects()
1255 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1257 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1259 foreach(QGraphicsItem
*item
, items
)
1261 addCommand(new Command::SendBackwardsItem(item
));
1268 * Trae al frente una unidad los elementos seleccionados.
1269 */void PaintArea::bringForwardsSelectedObjects()
1271 QList
<QGraphicsItem
*> items
= photogram()->selectedItems();
1273 DGraphics::Algorithm::sort(items
, DGraphics::Algorithm::ZAxis
);
1275 QList
<QGraphicsItem
*>::iterator it
= items
.end();
1277 while(it
!= items
.begin())
1280 addCommand(new Command::BringForwardsItem(*it
));
1286 * Copia los elementos seleccionados.
1288 void PaintArea::copySelectedObjects()
1290 QList
<QGraphicsItem
*> selecteds
= scene()->selectedItems();
1293 QDomElement root
= orig
.createElement("yamf-graphics");
1295 foreach(QGraphicsItem
*item
, selecteds
)
1297 int index
= currentFrame()->logicalIndexOf( item
);
1301 Model::Object
*graphic
= currentFrame()->graphic(index
);
1302 root
.appendChild(graphic
->toXml( orig
));
1306 orig
.appendChild(root
);
1308 QMimeData
*mimeData
= new QMimeData
;
1310 mimeData
->setData("yamf-graphics", orig
.toString().toLocal8Bit());
1311 //TODO: image/svg+xml
1312 QApplication::clipboard()->setMimeData( mimeData
);
1317 * Pega los elementos en el portapapeles.
1319 void PaintArea::pasteObjects()
1321 if( !currentFrame() ) return;
1323 const QMimeData
*mimeData
= QApplication::clipboard()->mimeData();
1325 QString xml
= mimeData
->data("yamf-graphics");
1328 if(!doc
.setContent(xml
))
1333 // TODO: image/svg+xml
1335 QDomElement docElem
= doc
.documentElement();
1336 QDomNode n
= docElem
.firstChild();
1340 QDomElement e
= n
.toElement();
1344 QTextStream
ts(&xml
);
1347 Model::Object
*object
= new Model::Object(currentFrame());
1348 object
->fromXml(xml
);
1350 currentFrame()->addObject(object
);
1352 n
= n
.nextSibling();
1354 d
->photogram
->drawCurrentPhotogram();
1359 * Corta los elementos seleccionados.
1361 void PaintArea::cutSelectedObjects()
1363 copySelectedObjects();
1364 removeSelectedObjects();
1369 * Selecciona todos los elementos en el area.
1371 void PaintArea::selectAllObjects()
1373 foreach(QGraphicsItem
*item
, photogram()->items() )
1375 item
->setFlag(QGraphicsItem::ItemIsSelectable
);
1376 item
->setSelected(true);
1382 * Añade lso elementos seleccionados a la biblioteca de objetos.
1384 void PaintArea::addToLibrary()
1386 QList
<QGraphicsItem
*> selecteds
= scene()->selectedItems();
1388 if ( selecteds
.isEmpty() )
1390 DGui::Osd::self()->display(tr("No items selected"), DGui::Osd::Error
);
1394 YAMF::Drawing::Private::AddSymbolDialog addSymbolDialog
;
1396 YAMF::Model::Library
*library
= d
->project
->library();
1398 QList
<QGraphicsItem
*> symbols
;
1400 foreach(QGraphicsItem
*item
, selecteds
)
1402 if( YAMF::Common::AbstractSerializable
*serializable
= dynamic_cast<YAMF::Common::AbstractSerializable
*>(item
) )
1404 addSymbolDialog
.addSymbol(item
);
1408 if( addSymbolDialog
.exec() == QDialog::Accepted
)
1410 for(int i
= 0; i
< addSymbolDialog
.symbolCount(); i
++)
1412 library
->addItemSymbol(addSymbolDialog
.symbol(i
), addSymbolDialog
.symbolName(i
));
1417 void PaintArea::applyCurrentSymbol()
1419 if( d
->photogram
->selectedItems().count() > 0 )
1421 if( Model::LibraryItem
*libraryItem
= qgraphicsitem_cast
<Model::LibraryItem
*>( d
->photogram
->selectedItems().first()) )
1423 YAMF::Command::ModifySymbol
*cmd
= new YAMF::Command::ModifySymbol(libraryItem
);
1432 * Añade un simbolo de la biblioteca identificado con @p id a el area .
1434 void PaintArea::addSymbol(const QString
&id
)
1436 YAMF::Model::LibraryObject
*object
= d
->project
->library()->findObject(id
);
1445 * Añade un simbolo @p object de la biblioteca a el area .
1447 void PaintArea::addSymbol(YAMF::Model::LibraryObject
*object
)
1449 YAMF::Model::Frame
*frame
= currentFrame();
1450 YAMF::Model::Scene
*scene
= currentScene();
1452 switch(object
->type())
1454 case YAMF::Model::LibraryObject::Sound
:
1456 Model::LibrarySoundObject
*soundObject
= dynamic_cast<Model::LibrarySoundObject
*>(object
);
1459 YAMF::Model::AudioLayer
*layer
= scene
->createAudioLayer();
1460 layer
->fromSymbol(soundObject
);
1464 case YAMF::Model::LibraryObject::Svg
:
1465 case YAMF::Model::LibraryObject::Item
:
1466 case YAMF::Model::LibraryObject::Image
:
1467 case YAMF::Model::LibraryObject::Text
:
1471 YAMF::Model::LibraryItem
*item
= new YAMF::Model::LibraryItem(object
);
1472 frame
->addItem(item
);
1482 void PaintArea::recordItem()
1484 Model::Frame
*frame
= currentFrame();
1486 if( frame
&& d
->photogram
->selectedItems().count() > 0 )
1488 QGraphicsItem
*item
= d
->photogram
->selectedItems().first();
1490 int logicalIndex
= frame
->logicalIndexOf(item
);
1492 if( logicalIndex
> -1 )
1494 d
->photogram
->recordObject(frame
->graphic(logicalIndex
));
1504 void PaintArea::stopRecordItem()
1506 Model::Object
*object
= d
->photogram
->recorded();
1507 Model::Frame
*frame
= currentFrame();
1509 int framePos
= frame
->visualIndex();
1510 int objectPos
= object
->frame()->visualIndex();
1512 if( object
&& framePos
> objectPos
)
1514 int stepsCount
= framePos
- objectPos
;
1516 Item::Tweener
*tweener
= new Item::Tweener(stepsCount
, object
);
1518 foreach(Private::RecordStep rs
, d
->steps
)
1520 tweener
->addStep(*rs
.step
);
1524 object
->setTweener(tweener
);
1527 d
->photogram
->recordObject(0);