modify abstracttool iface
[yamf.git] / yamf / tools / polyline / polyline.cpp
blob297837cf0c58668a85201dd6cbc1df379aab4562
1 /***************************************************************************
2 * Copyright (C) 2007 by Jorge Cuadrado *
3 * kuadrosxx@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 "polyline.h"
23 #include <drawing/photogram.h>
24 #include <drawing/brushmanager.h>
25 #include <drawing/paintarea.h>
27 #include <dgraphics/patheditor.h>
28 #include <dgui/action.h>
29 #include <dgui/iconloader.h>
30 #include <dcore/debug.h>
32 #include <selection/private/contoureditor.h>
33 #include <model/command/editnodesitem.h>
35 #include <model/frame.h>
36 #include <item/path.h>
39 #include <QPointF>
40 #include <QIcon>
41 #include <QKeySequence>
42 #include <QGraphicsPathItem>
43 #include <QPainterPath>
44 #include <QMatrix>
45 #include <QGraphicsLineItem>
46 #include <QGraphicsView>
48 #include <QGraphicsSceneMouseEvent>
49 #include <QKeyEvent>
52 namespace YAMF {
53 namespace Drawing {
54 namespace Tool {
56 struct PolyLine::Private
58 bool begin, moved;
59 QPointF center;
60 QPointF right;
61 Drawing::Tool::Private::ContourEditor *editor;
62 QPainterPath path;
63 QPainterPath lastPart;
65 YAMF::Item::Path *item;
66 PaintArea * paintArea;
67 DGui::Action *action;
69 QGraphicsLineItem *line1, *line2;
71 QGraphicsPathItem *line3;
74 /**
75 * @~spanish
76 * Construye la herramienta para dibujar trazos rectos y curvilíneos.
78 PolyLine::PolyLine(QObject *parent): AbstractTool(parent), d(new Private)
80 d->begin = false;
82 d->editor = 0;
83 d->item = 0;
84 d->paintArea = 0;
85 d->line1 = new QGraphicsLineItem(0,0,0,0);
86 d->line1->setPen ( QPen(Qt::red) );
87 d->line2 = new QGraphicsLineItem(0,0,0,0);
88 d->line2->setPen ( QPen(Qt::green) );
90 d->line3 = new QGraphicsPathItem();
92 d->action = new DGui::Action( DGui::IconLoader::self()->load("draw-path.svg"), tr("Poly line"), this);
93 d->action->setShortcut( QKeySequence(tr("")) );
97 /**
98 * Destructor
100 PolyLine::~PolyLine()
102 delete d;
106 * @~spanish
107 * Inicializa la herramienta, evita que los items dentro de el fotograma se puedan mover o seleccionar.
109 void PolyLine::init(Photogram *photogram)
111 endItem();
112 //FIXME
113 foreach(QGraphicsView *view, photogram->views() )
115 view->setDragMode ( QGraphicsView::NoDrag );
117 Q_CHECK_PTR(view->scene());
118 if ( QGraphicsScene *sscene = qobject_cast<QGraphicsScene *>(view->scene()) )
120 foreach(QGraphicsItem *item, sscene->items() )
122 item->setFlag(QGraphicsItem::ItemIsSelectable, false);
123 item->setFlag(QGraphicsItem::ItemIsMovable, false);
125 sscene->addItem( d->line1 );
126 sscene->addItem( d->line2 );
132 * @~spanish
133 * Retorna el id de la herramienta.
135 QString PolyLine::id() const
137 return tr("PolyLine");
141 * @~spanish
142 * Función sobrecargada para implementar la creación de los trazos rectos y curvilíneos.
144 void PolyLine::press(const QGraphicsSceneMouseEvent *input)
146 d->paintArea = this->paintArea(); // FIXME
147 QGraphicsScene *scene = d->paintArea->scene();
148 if(scene->items().contains(d->line3))
150 scene->removeItem(d->line3);
153 BrushManager *brushManager = d->paintArea->brushManager();
155 scene->clearSelection();
157 if(!d->item)
159 d->path = QPainterPath();
160 d->path.moveTo(input->scenePos());
162 d->item = new YAMF::Item::Path();
163 d->item->setZValue(1000);
164 d->editor = new Drawing::Tool::Private::ContourEditor(d->item, scene);
165 connect(d->editor, SIGNAL(nodeClicked()), this, SLOT(nodeChanged()));
166 scene->addItem( d->item );
168 d->begin = true;
169 d->moved = false;
171 else
173 d->begin = false;
175 if(!d->moved)
177 d->path.cubicTo(d->center, d->center, input->scenePos());
178 d->editor->save();
179 d->item->setPath(d->path);
180 d->paintArea->brushManager()->map(d->item);
182 else
184 d->moved = false;
185 d->path.cubicTo(d->center, d->right, input->scenePos());
186 d->editor->save();
187 d->item->setPath(d->path);
188 d->paintArea->brushManager()->map(d->item);
192 d->center = input->scenePos();
194 d->item->setPen( brushManager->pen() );
198 * @~spanish
199 * Función sobrecargada para implementar la creación de los trazos rectos y curvilíneos.
201 void PolyLine::move(const QGraphicsSceneMouseEvent *input)
203 PaintArea *paintArea = this->paintArea();
204 QGraphicsScene *scene = paintArea->scene();
205 if(d->item)
207 if(input->buttons() == Qt::NoButton)
209 QPainterPath lastPart;
211 lastPart.moveTo(d->center);
213 if(!d->moved)
215 // lastPart.lineTo(input->scenePos());
216 lastPart.cubicTo(d->center, d->center, input->scenePos());
218 else
220 lastPart.cubicTo(d->center, d->right, input->scenePos());
223 d->line3->setPath(lastPart);
224 if(!scene->items().contains(d->line3))
226 scene->addItem(d->line3);
229 if(!scene->items().contains(d->line1))
231 scene->addItem( d->line1 );
233 if(!scene->items().contains(d->line2))
235 scene->addItem( d->line2 );
238 else if(d->editor && d->editor->isSelected())
240 d->path = d->item->path();
242 else if(input->buttons() == Qt::LeftButton)
244 paintArea->setDragMode(QGraphicsView::NoDrag);
246 if(d->begin)
248 d->moved = true;
249 d->right = input->scenePos();
251 d->line2->setLine(QLineF(d->right, d->center));
252 if(!scene->items().contains(d->line2))
254 scene->addItem( d->line2 );
257 else
259 int index = d->path.elementCount()-3;
261 if( d->path.elementAt(index).type == QPainterPath::CurveToElement )
263 if(!d->moved)
265 QPointF point = d->path.elementAt(index+1);
266 d->path.setElementPositionAt(index, point.x(), point.y() );
269 QPointF mirror = d->center - ( input->scenePos() - d->center);
271 d->path.setElementPositionAt(index+1, mirror.x(), mirror.y());
273 d->line1->setLine(QLineF(mirror, d->center));
274 d->line2->setLine(QLineF(d->right, d->center));
276 if(!scene->items().contains(d->line1))
278 scene->addItem( d->line1 );
280 if(!scene->items().contains(d->line2))
282 scene->addItem( d->line2 );
286 d->moved = true;
287 d->right = input->scenePos();
288 d->item->setPath(d->path);
289 paintArea->brushManager()->map(d->item);
297 * @~spanish
298 * Función sobrecargada para implementar la creación de los trazos rectos y curvilíneos.
300 void PolyLine::release(const QGraphicsSceneMouseEvent *input)
302 Q_UNUSED(input);
303 PaintArea *paintArea = this->paintArea();
305 d->editor->expandAllNodes ();
308 if(d->begin)
310 paintArea->currentFrame()->addItem(d->item);
312 else if(!d->editor->isSelected())
314 int position = paintArea->currentFrame()->visualIndexOf(d->item);
316 if(position > -1)
318 paintArea->addCommand(new Command::EditNodesItem(d->item, d->editor->oldPath(), paintArea->currentFrame()));
319 d->editor->save();
325 * @~spanish
326 * Función sobrecargada para implementar la creación de los trazos rectos y curvilíneos.
327 * termina de hacer el trazo.
329 void PolyLine::doubleClick(const QGraphicsSceneMouseEvent *input)
331 Q_UNUSED(input);
333 endItem();
337 void PolyLine::keyPressEvent(QKeyEvent *event)
339 if(event->key() == Qt::Key_Escape)
341 endItem();
342 event->accept();
347 * @~spanish
348 * Retorna la acción que representa la herramienta.
350 DGui::Action *PolyLine::action() const
352 return d->action;
356 * @~spanish
357 * Retorna que la herramienta es de tipo Brush.
359 int PolyLine::type() const
361 return AbstractTool::Brush;
365 * @~spanish
366 * Función sobrecargada para terminar de crear el ítem, cuando se cambia la herramienta.
368 void PolyLine::aboutToChangeTool()
370 endItem();
374 * Función sobrecargada para actualizar valores cuando hay un cambio en el fotograma.
376 void PolyLine::photogramChanged(Photogram *const photogram)
378 Q_UNUSED(photogram);
379 if(d->item)
381 // d->path = d->item->path();
382 // d->editor->setItem(d->item);
383 if(!d->item->path().isEmpty())
385 d->editor->show();
387 // d->editor->expandAllNodes();
388 int size = d->item->path().elementCount();
389 if(size > 0)
391 d->center = d->item->path().elementAt(size -1);
397 * @internal
398 * Termina de crear el trazo.
400 void PolyLine::endItem()
402 if(d->item)
404 d->path = QPainterPath();
405 d->item = 0;
406 delete d->editor;
407 d->editor = 0;
412 * @internal
413 * Actualiza los valores cuando se modifican los nodos de trazo.
415 void PolyLine::nodeChanged()
417 if(d->paintArea)
419 int position = d->paintArea->currentFrame()->visualIndexOf(d->item);
421 if(position != -1)
423 int size = d->item->path().elementCount();
424 if(size > 0)
426 d->center = d->item->path().elementAt(size -1);
428 d->path = d->item->path();
429 d->paintArea->addCommand(new Command::EditNodesItem(d->item, d->editor->oldPath(), d->paintArea->currentFrame()));
430 d->editor->save();