modify abstracttool iface
[yamf.git] / yamf / drawing / paintarea.cpp
blobe6c693938e6b1b7ddbada1310f478a74b48bf411
1 /***************************************************************************
2 * Copyright (C) 2005 by Jorge Cuadrado *
3 * kuadrosxx@gmail.com *
4 * Copyright (C) 2006 by David Cuadrado *
5 * krawek@gmail.com *
6 * *
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. *
11 * *
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. *
16 * *
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>
31 #include <QPolygon>
32 #include <QApplication>
33 #include <QTimer>
34 #include <QStyleOptionGraphicsItem>
35 #include <QClipboard>
36 #include <QUndoStack>
37 #include <QMenu>
38 #include <QToolBar>
40 #include "photogram.h"
41 #include <dgraphics/algorithm.h>
43 #include <dcore/config.h>
44 #include <dcore/debug.h>
45 #include <dgui/application.h>
46 #include <dgui/osd.h>
47 #include <dgui/commandhistory.h>
48 #include <dgui/action.h>
49 #include <dgui/actionmanager.h>
50 #include <dgui/iconloader.h>
52 #include <cmath>
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>
87 namespace YAMF {
88 namespace Drawing {
90 #ifdef QT_OPENGL_LIB
92 #include <QGLWidget>
93 #include <QGLFramebufferObject>
95 class GLDevice : public QGLWidget
97 public:
98 GLDevice() : QGLWidget()
100 makeCurrent();
102 ~GLDevice() {};
104 protected:
105 void initializeGL()
107 glDisable(GL_DEPTH_TEST);
110 #endif
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;
122 QRectF drawingRect;
124 bool drawGrid;
125 double angle;
127 YAMF::Drawing::Private::PaintAreaRotator *rotator;
128 Photogram *photogram;
130 struct FramePosition {
131 int layer;
132 int frame;
133 } framePosition;
136 struct ItemProperties {
137 QGraphicsItem *item;
138 QString properties;
141 QList<ItemProperties> properties;
143 QPointF origin;
145 DGui::ActionManager actionManager;
147 Model::Project *const project;
149 double lastScaleFactor;
151 QToolBar *toolsConfigBar;
152 QToolBar *effectsConfigBar;
156 * @~spanish
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);
165 d->drawGrid = false;
166 d->angle = 0;
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);
175 centerDrawingArea();
177 setUseOpenGL( false );
178 setInteractive ( true );
180 restoreState();
182 setCurrentFrame(-1, -1, -1);
184 d->origin = mapToScene(QPoint(0, 0));
186 createActions();
187 checkActions();
189 d->toolsConfigBar = new QToolBar(tr("Configure tool"), this);
191 d->effectsConfigBar = new QToolBar(tr("Configure effects"), this);
195 * @~spanish
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);
205 config->endGroup();
209 * @~spanish
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);
222 config->endGroup();
226 * Destructor
228 PaintArea::~PaintArea()
230 saveState();
232 d->toolsConfigBar->clear();
233 d->effectsConfigBar->clear();
236 delete d->photogram;
237 delete d;
242 * @~spanish
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()));
255 addAction(remove);
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()));
265 addAction(copy);
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()));
270 addAction(paste);
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()));
275 addAction(cut);
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");
286 /////////
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");
292 addAction(group);
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");
298 addAction(ungroup);
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);
324 // Library
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");
338 * @~spanish
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)
343 #ifdef QT_OPENGL_LIB
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);
350 #endif
352 setRenderHint(QPainter::Antialiasing, use);
353 setRenderHint(QPainter::TextAntialiasing, use);
357 * @~spanish
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);
365 if ( viewport() )
367 cursor = viewport()->cursor();
370 #ifdef QT_OPENGL_LIB
371 if ( opengl )
373 setViewport(new GLDevice());
375 else
377 // setViewport( new KTImageDevice() );
379 #else
380 Q_UNUSED(opengl);
381 dWarning() << tr("OpenGL isn't supported");
382 #endif
384 // to restore the cursor.
385 if ( viewport() )
387 viewport()->setCursor(cursor);
388 viewport()->setAcceptDrops(true);
393 * @~spanish
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)
399 d->drawGrid = draw;
400 // resetCachedContent();
401 viewport()->update();
405 * @~spanish
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);
424 * @~spanish
425 * Retorna si esta activo el dibujo de la grilla.
427 bool PaintArea::drawGrid() const
429 return d->drawGrid;
432 void PaintArea::mousePressEvent( QMouseEvent * event )
434 if ( !canPaint() ) return;
436 QGraphicsItem *item = d->photogram->itemAt( mapToScene(event->pos()) );
438 d->effectsConfigBar->clear();
439 if( item )
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();
452 if( item )
454 // Add effects
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"));
477 else
479 menu->addAction(d->actionManager.find("addtolibrary", "library"));
482 menu->addSeparator();
484 checkActions();
486 menu->exec(event->globalPos());
488 delete menu;
490 else
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;
501 prop.item = item;
503 QDomDocument doc;
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;
516 // Rotate
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);
533 else
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*/)
580 QDomDocument doc;
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();
593 checkActions();
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;
610 painter->save();
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 )
625 d->origin = origin;
626 emit originChanged( d->origin );
629 if ( d->drawGrid )
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);
648 painter->restore();
652 * @~spanish
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);
673 * @~spanish
674 * Retorna verdadero si se puede dibujar sobre el area de dibujo y falso si no.
676 bool PaintArea::canPaint() const
678 if( d->photogram )
680 Model::Frame *frame = currentFrame();
682 if( frame )
684 return !frame->isLocked() && !frame->layer()->isLocked();
688 return false;
692 * @~spanish
693 * Centra la vista del fotograma.
695 void PaintArea::centerDrawingArea()
697 centerOn(d->drawingRect.center());
701 * @internal
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();
717 * @internal
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));
733 if( object )
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);
742 addCommand(cmd);
747 void PaintArea::wheelEvent(QWheelEvent *event)
749 if(event->modifiers () == Qt::ControlModifier)
751 scaleView(pow(( double)2, -event->delta() / 240.0));
753 else
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();
771 return ret;
775 * @~spanish
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)
782 return;
785 d->lastScaleFactor *= scaleFactor;
786 scale(scaleFactor, scaleFactor);
788 emit scaled(d->lastScaleFactor);
792 * @~spanish
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);
809 emit scaled(factor);
813 * @~spanish
814 * Rota la vista sobre el fotograma.
816 void PaintArea::setRotationAngle(int angle)
818 rotate(angle - d->angle );
819 d->angle = angle;
823 * @~spanish
824 * Retorna el manejador de brochas del area de dibujo.
826 BrushManager *PaintArea::brushManager() const
828 return d->photogram->brushManager();
832 * @~spanish
833 * Retorna el area en la cual va aparecer en la animación.
835 QRectF PaintArea::drawingRect() const
837 return d->drawingRect;
841 * @~spanish
842 * Retorna el fotograma actual.
844 Photogram *PaintArea::photogram() const
846 return d->photogram;
850 * @~spanish
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);
858 // if( scene )
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();
870 * @~spanish
871 * Retorna el proyecto asociado al area de dibujo.
873 Model::Project *PaintArea::project() const
875 return d->project;
879 * @~spanish
880 * Retorna la escena actual.
882 Model::Scene *PaintArea::currentScene() const
884 return d->photogram->scene();
888 * @~spanish
889 * Retorna la capa actual.
891 Model::Layer *PaintArea::currentLayer() const
893 Model::Scene *scene = d->photogram->scene();
895 if( scene )
897 return scene->layer(d->framePosition.layer);
901 return 0;
905 * @~spanish
906 * Retorna el frame actual.
908 Model::Frame *PaintArea::currentFrame() const
910 Model::Layer *layer = currentLayer();
912 if( layer )
914 return layer->frame(d->framePosition.frame);
918 return 0;
922 * @~spanish
925 void PaintArea::addCommand(Command::Base *command)
927 d->project->commandManager()->addCommand(command);
931 * @~spanish
932 * Retorna la historia de comandos
933 * @return
935 DGui::CommandHistory *PaintArea::history() const
937 return d->history;
941 * @~spanish
942 * Retorna la acción que permite remover los elementos seleccionados en el area.
943 * @return
945 QAction *PaintArea::removeAction()
947 return d->actionManager.find("remove", "edit");
951 * @~spanish
952 * Retorna la acción que permite agrupar los elementos seleccionados en el area.
953 * @return
955 QAction *PaintArea::groupAction()
957 return d->actionManager.find("group", "object");
961 * @~spanish
962 * Retorna la acción que permite des-agrupar los elementos seleccionados en el area.
963 * @return
965 QAction *PaintArea::ungroupAction()
967 return d->actionManager.find("ungroup", "object");
971 * @~spanish
972 * Retorna la acción que permite enviar al fondo los elementos seleccionados en el area.
973 * @return
975 QAction *PaintArea::sendToBackAction()
977 return d->actionManager.find( "sendtoback", "object-order");
981 * @~spanish
982 * Retorna la acción que permite enviar al frente los elementos seleccionados en el area.
983 * @return
985 QAction *PaintArea::bringToFrontAction()
987 return d->actionManager.find( "bringtofront", "object-order");
992 * @~spanish
993 * Retorna la acción que permite enviar hacia atras una unidad los elementos seleccionados en el area.
994 * @return
996 QAction *PaintArea::sendBackwardsAction()
998 return d->actionManager.find( "sendbackwards", "object-order");
1002 * @~spanish
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");
1011 * @~spanish
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");
1020 * @~spanish
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");
1029 * @~spanish
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");
1038 * @~spanish
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");
1047 * @~spanish
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);
1078 return menu;
1082 * @~spanish
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;
1091 * @~spanish
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);
1109 else
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);
1123 else
1125 d->actionManager.find("paste", "edit")->setEnabled(false);
1130 * @~spanish
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();
1145 * @~spanish
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()));
1158 * @~spanish
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()));
1178 * @~spanish
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);
1191 if(o)
1193 addCommand(new Command::SendToBackItem(o));
1199 * @~spanish
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())
1214 --it;
1215 Model::Object *o = frame->graphic(*it);
1216 if(o)
1218 addCommand(new Command::BringToFrontItem(o));
1224 * @~spanish
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);
1237 if(o)
1239 addCommand(new Command::SendBackwardsItem(o));
1246 * @~spanish
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())
1261 --it;
1262 Model::Object *o = frame->graphic(*it);
1263 if(o)
1265 addCommand(new Command::BringForwardsItem(o));
1271 * @~spanish
1272 * Copia los elementos seleccionados.
1274 void PaintArea::copySelectedObjects()
1276 QList<QGraphicsItem *> selecteds = scene()->selectedItems();
1278 QDomDocument orig;
1279 QDomElement root = orig.createElement("yamf-graphics");
1281 foreach(QGraphicsItem *item, selecteds)
1283 int index = currentFrame()->visualIndexOf( item );
1285 if(index > -1)
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 );
1302 * @~spanish
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");
1313 QDomDocument doc;
1314 if(!doc.setContent(xml))
1316 return;
1319 // TODO: image/svg+xml
1321 QDomElement docElem = doc.documentElement();
1322 QDomNode n = docElem.firstChild();
1324 while(!n.isNull())
1326 QDomElement e = n.toElement();
1327 if(!e.isNull())
1329 QString xml;
1330 QTextStream ts(&xml);
1331 ts << e;
1333 Model::Object *object = new Model::Object(currentFrame());
1334 object->fromXml(xml);
1336 currentFrame()->addObject(object);
1338 n = n.nextSibling();
1340 d->photogram->drawCurrentPhotogram();
1344 * @~spanish
1345 * Corta los elementos seleccionados.
1347 void PaintArea::cutSelectedObjects()
1349 copySelectedObjects();
1350 removeSelectedObjects();
1354 * @~spanish
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);
1367 * @~spanish
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);
1377 return;
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);
1411 addCommand(cmd);
1417 * @~spanish
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);
1423 if( object )
1425 addSymbol(object);
1430 * @~spanish
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);
1443 if ( scene != 0 )
1445 YAMF::Model::AudioLayer *layer = scene->createAudioLayer();
1446 layer->fromSymbol(soundObject);
1449 break;
1450 case YAMF::Model::LibraryObject::Svg:
1451 case YAMF::Model::LibraryObject::Item:
1452 case YAMF::Model::LibraryObject::Image:
1453 case YAMF::Model::LibraryObject::Text:
1455 if( frame != 0 )
1457 YAMF::Model::LibraryItem *item = new YAMF::Model::LibraryItem(object);
1458 frame->addItem(item);
1461 break;