Implemented tweening by position
[yamf.git] / yamf / drawing / photogram.cpp
blob797ef88cc618695717707fd1fb72cd56b75184d9
1 /***************************************************************************
2 * Copyright (C) 2006 by David Cuadrado *
3 * krawek@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "photogram.h"
23 #include <QGraphicsItem>
24 #include <QGraphicsView>
25 #include <QStyleOptionGraphicsItem>
26 #include <QGraphicsSceneMouseEvent>
27 #include <QKeyEvent>
29 #include <model/scene.h>
30 #include <model/layer.h>
31 #include <model/frame.h>
32 #include <model/object.h>
34 #include "item/group.h"
37 #include <drawing/abstracttool.h>
38 #include <drawing/brushmanager.h>
39 #include <drawing/paintarea.h>
41 #include "item/tweener.h"
43 #include <dcore/debug.h>
45 #include <private/guide.h>
47 namespace YAMF {
48 namespace Drawing {
50 struct Photogram::Private
52 Private() : tool(0), scene(0), position(0), isDrawing(false), recorded(false) {}
54 AbstractTool *tool;
55 Model::Scene *scene;
56 struct OnionSkin
58 int previous;
59 int next;
60 QHash<QGraphicsItem *, double> opacityMap;
61 } onionSkin;
63 int position;
65 bool isDrawing;
66 BrushManager *brushManager;
67 PaintArea *paintArea;
69 QList<YAMF::Drawing::Private::Guide *> guides;
71 Model::Object *recorded;
74 Photogram::Photogram(PaintArea *parent) : QGraphicsScene(parent), d(new Private)
76 d->paintArea = parent;
78 setItemIndexMethod(QGraphicsScene::NoIndex);
80 d->onionSkin.next = 0;
81 d->onionSkin.previous = 0;
82 d->isDrawing = false;
84 setBackgroundBrush(Qt::gray);
86 d->brushManager = new BrushManager(this);
90 Photogram::~Photogram()
92 D_END;
94 clearFocus();
95 clearSelection();
97 foreach( QGraphicsView *view, this->views() )
99 view->setScene(0);
102 foreach(QGraphicsItem *item, items())
104 removeItem(item);
107 delete d;
110 void Photogram::setCurrent(int pos)
112 d->position = pos;
115 void Photogram::drawCurrentPhotogram()
117 drawPhotogram( d->position );
122 void Photogram::drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget)
124 for (int i = 0; i < numItems; ++i)
126 QGraphicsItem *item = items[i];
127 painter->save();
128 painter->setMatrix(item->sceneMatrix(), true);
130 if ( d->onionSkin.opacityMap.contains(item) )
132 painter->setOpacity( d->onionSkin.opacityMap[item] );
135 item->paint(painter, &options[i], widget);
137 painter->restore();
142 void Photogram::drawPhotogram(int photogram)
144 if ( photogram < 0 || !d->scene ) return;
147 if( d->tool )
148 d->tool->aboutToChangePhotogram(this);
150 clean();
152 bool valid = false;
154 foreach(Model::Layer *layer, d->scene->layers().values())
156 if ( layer->isVisible() )
158 if( d->onionSkin.previous > 0 )
160 double opacityFactor = 0.5 / (double)qMin(layer->frames().count(),d->onionSkin.previous);
162 double opacity = 0.6;
164 for(int frameIndex = photogram-1; frameIndex > photogram-d->onionSkin.previous-1; frameIndex-- )
166 Model::Frame * frame = layer->frame(frameIndex);
167 if(frame)
169 addFrame( frame, opacity );
171 opacity -= opacityFactor;
175 if ( d->onionSkin.next > 0 )
177 double opacityFactor = 0.5 / (double)qMin(layer->frames().count(), d->onionSkin.next);
178 double opacity = 0.6;
180 for(int frameIndex = photogram+1; frameIndex < photogram+d->onionSkin.next+1; frameIndex++ )
183 Model::Frame * frame = layer->frame(frameIndex);
184 if(frame)
186 addFrame( frame, opacity );
188 opacity -= opacityFactor;
192 Model::Frame *frame = layer->frame( photogram );
194 if( frame )
196 valid = true;
197 addFrame(frame);
202 if( valid )
204 if( d->recorded )
206 if( d->recorded->frame()->isVisible() )
208 addItem(d->recorded->item());
212 foreach(Model::Object *object, d->scene->tweeningObjects())
214 if(object->frame()->layer()->isVisible() )
216 int origin = object->frame()->visualIndex();
218 if( Item::Tweener *tweener = object->tweener() )
220 tweener->setStep(0);
222 if( origin < photogram && photogram < origin+tweener->frames() )
224 int step = photogram - origin;
226 tweener->setStep(step);
228 addGraphicObject(object);
234 update();
237 if( d->tool )
239 d->tool->photogramChanged(this);
243 void Photogram::addFrame(Model::Frame *frame, double opacity )
245 if ( frame->isVisible() )
247 foreach(Model::Object *object, frame->graphics().values() )
249 addGraphicObject(object, opacity);
254 void Photogram::addGraphicObject(Model::Object *object, double opacity)
256 QGraphicsItem *item = object->item();
258 if( item )
260 d->onionSkin.opacityMap.insert(item, opacity);
262 if ( Item::Group *group = qgraphicsitem_cast<Item::Group *>(item) )
264 group->recoverChilds();
267 if( ! qgraphicsitem_cast<Item::Group *>(item->parentItem()))
269 addItem(item);
274 void Photogram::clean()
276 d->onionSkin.opacityMap.clear();
278 foreach(QGraphicsItem *item, items() )
280 if ( item->scene() == this )
282 removeItem(item);
286 foreach(YAMF::Drawing::Private::Guide *guide, d->guides )
288 addItem(guide);
292 void Photogram::setNextOnionSkinCount(int n)
294 d->onionSkin.next = n;
295 drawCurrentPhotogram();
298 void Photogram::setPreviousOnionSkinCount(int n)
300 d->onionSkin.previous = n;
302 drawCurrentPhotogram();
305 void Photogram::setCurrentScene(Model::Scene *scene)
307 qDeleteAll(d->guides);
308 d->guides.clear();
310 clean();
311 d->scene = scene;
313 drawCurrentPhotogram();
316 void Photogram::setLayerVisible(int layerIndex, bool visible)
318 if( !d->scene ) return;
320 if( Model::Layer *layer = d->scene->layer(layerIndex) )
322 layer->setVisible(visible);
326 Model::Scene *Photogram::scene() const
328 return d->scene;
331 void Photogram::setTool(AbstractTool *tool)
333 drawCurrentPhotogram();
334 if(d->tool)
336 if(d->tool->type() == AbstractTool::Selection )
338 foreach(YAMF::Drawing::Private::Guide *guide, d->guides)
340 guide->setFlag( QGraphicsItem::ItemIsMovable, false );
341 guide->setEnabledSyncCursor(true);
344 d->tool->aboutToChangeTool();
347 d->tool = tool;
348 if(tool->type() == AbstractTool::Selection )
350 foreach(YAMF::Drawing::Private::Guide *guide, d->guides)
352 guide->setFlag( QGraphicsItem::ItemIsMovable, true );
353 guide->setEnabledSyncCursor(false);
356 d->tool->init(this);
360 AbstractTool *Photogram::currentTool() const
362 return d->tool;
366 void Photogram::mousePressEvent(QGraphicsSceneMouseEvent *event)
368 QGraphicsScene::mousePressEvent(event);
370 d->isDrawing = false;
372 if( event->buttons() == Qt::LeftButton && (event->modifiers () == (Qt::ShiftModifier | Qt::ControlModifier)))
375 else if (d->tool )
377 if( d->tool->type() == AbstractTool::Brush && event->isAccepted() ) return;
379 if( d->position > -1 )
381 if ( event->buttons() == Qt::LeftButton )
383 d->isDrawing = true;
384 d->tool->press(event, d->paintArea);
390 void Photogram::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
392 QGraphicsScene::mouseMoveEvent(event);
393 mouseMoved(event);
396 void Photogram::mouseMoved(QGraphicsSceneMouseEvent *event)
398 // d->inputInformation->updateFromMouseEvent( event );
400 if (d->tool /*&& d->isDrawing*/ )
402 d->tool->move(event, d->paintArea );
406 void Photogram::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
408 QGraphicsScene::mouseReleaseEvent(event);
409 mouseReleased(event);
412 void Photogram::mouseReleased(QGraphicsSceneMouseEvent *event)
414 // d->inputInformation->updateFromMouseEvent( event );
416 if ( d->tool && d->isDrawing )
418 d->tool->release(event, d->paintArea );
419 // drawCurrentPhotogram(); FIXME esto borra los nodos
422 d->isDrawing = false;
425 void Photogram::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
427 QGraphicsScene::mouseDoubleClickEvent(event);
429 // d->inputInformation->updateFromMouseEvent( event );
431 if(d->tool)
433 d->tool->doubleClick( event, d->paintArea );
437 void Photogram::keyPressEvent(QKeyEvent *event)
439 if ( d->tool )
441 d->tool->keyPressEvent(event);
443 if ( event->isAccepted() )
445 return;
449 QGraphicsScene::keyPressEvent(event);
453 void Photogram::dragEnterEvent ( QGraphicsSceneDragDropEvent * event )
456 if (event->mimeData()->hasFormat("yamf-ruler"))
458 event->acceptProposedAction();
459 YAMF::Drawing::Private::Guide *guide = 0;
460 if(event->mimeData()->data("yamf-ruler") == "verticalLine")
462 guide = new YAMF::Drawing::Private::Guide(Qt::Vertical, this);
463 guide->setPos(event->scenePos());
465 else
467 guide = new YAMF::Drawing::Private::Guide(Qt::Horizontal, this);
468 guide->setPos(event->scenePos());
471 if(guide)
473 d->guides << guide;
479 void Photogram::dragLeaveEvent ( QGraphicsSceneDragDropEvent * event)
481 if (event->mimeData()->hasFormat("yamf-ruler"))
483 removeItem(d->guides.last());
484 delete d->guides.takeLast();
488 void Photogram::dragMoveEvent ( QGraphicsSceneDragDropEvent * event )
490 if (event->mimeData()->hasFormat("yamf-ruler"))
492 if(!d->guides.isEmpty())
494 d->guides.last()->setPos(event->scenePos());
499 void Photogram::dropEvent ( QGraphicsSceneDragDropEvent * event )
501 Q_UNUSED(event);
502 if(d->tool)
504 if(d->tool->type() == AbstractTool::Selection )
506 d->guides.last()->setEnabledSyncCursor(false);
507 d->guides.last()->setFlag( QGraphicsItem::ItemIsMovable, true );
513 bool Photogram::event(QEvent *e)
515 return QGraphicsScene::event(e);
518 bool Photogram::isDrawing() const
520 return d->isDrawing;
523 Model::Object *Photogram::recorded() const
525 return d->recorded;
528 void Photogram::recordObject(Model::Object *record)
530 d->recorded = record;
533 BrushManager *Photogram::brushManager() const
535 return d->brushManager;
538 void Photogram::aboutToMousePress()
540 QHash<QGraphicsItem *, double>::iterator it = d->onionSkin.opacityMap.begin();
542 while(it != d->onionSkin.opacityMap.end() )
544 if( it.value() != 1.0 )
546 it.key()->setAcceptedMouseButtons(Qt::NoButton);
547 it.key()->setFlag(QGraphicsItem::ItemIsSelectable, false);
549 else
551 it.key()->setAcceptedMouseButtons( Qt::LeftButton | Qt::RightButton | Qt::MidButton | Qt::XButton1 | Qt::XButton2 );
554 ++it;