1 /***************************************************************************
2 * Copyright (C) 2006 by David Cuadrado *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "photogram.h"
23 #include <QGraphicsItem>
24 #include <QGraphicsView>
25 #include <QStyleOptionGraphicsItem>
26 #include <QGraphicsSceneMouseEvent>
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>
50 struct Photogram::Private
52 Private() : tool(0), scene(0), position(0), isDrawing(false), recorded(false) {}
60 QHash
<QGraphicsItem
*, double> opacityMap
;
66 BrushManager
*brushManager
;
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;
84 setBackgroundBrush(Qt::gray
);
86 d
->brushManager
= new BrushManager(this);
90 Photogram::~Photogram()
97 foreach( QGraphicsView
*view
, this->views() )
102 foreach(QGraphicsItem
*item
, items())
110 void Photogram::setCurrent(int 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
];
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
);
142 void Photogram::drawPhotogram(int photogram
)
144 if ( photogram
< 0 || !d
->scene
) return;
148 d
->tool
->aboutToChangePhotogram(this);
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
);
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
);
186 addFrame( frame
, opacity
);
188 opacity
-= opacityFactor
;
192 Model::Frame
*frame
= layer
->frame( photogram
);
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() )
222 if( origin
< photogram
&& photogram
< origin
+tweener
->frames() )
224 int step
= photogram
- origin
;
226 tweener
->setStep(step
);
228 addGraphicObject(object
);
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();
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()))
274 void Photogram::clean()
276 d
->onionSkin
.opacityMap
.clear();
278 foreach(QGraphicsItem
*item
, items() )
280 if ( item
->scene() == this )
286 foreach(YAMF::Drawing::Private::Guide
*guide
, d
->guides
)
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
);
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
331 void Photogram::setTool(AbstractTool
*tool
)
333 drawCurrentPhotogram();
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();
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);
360 AbstractTool
*Photogram::currentTool() const
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
)))
377 if( d
->tool
->type() == AbstractTool::Brush
&& event
->isAccepted() ) return;
379 if( d
->position
> -1 )
381 if ( event
->buttons() == Qt::LeftButton
)
384 d
->tool
->press(event
, d
->paintArea
);
390 void Photogram::mouseMoveEvent(QGraphicsSceneMouseEvent
*event
)
392 QGraphicsScene::mouseMoveEvent(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 );
433 d
->tool
->doubleClick( event
, d
->paintArea
);
437 void Photogram::keyPressEvent(QKeyEvent
*event
)
441 d
->tool
->keyPressEvent(event
);
443 if ( event
->isAccepted() )
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());
467 guide
= new YAMF::Drawing::Private::Guide(Qt::Horizontal
, this);
468 guide
->setPos(event
->scenePos());
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
)
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
523 Model::Object
*Photogram::recorded() const
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);
551 it
.key()->setAcceptedMouseButtons( Qt::LeftButton
| Qt::RightButton
| Qt::MidButton
| Qt::XButton1
| Qt::XButton2
);