1 /***************************************************************************
2 * Copyright (C) 2007 by Jorge Cuadrado *
3 * kuadrosxx@gmail.com *
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 ***************************************************************************/
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>
41 #include <QKeySequence>
42 #include <QGraphicsPathItem>
43 #include <QPainterPath>
45 #include <QGraphicsLineItem>
46 #include <QGraphicsView>
48 #include <QGraphicsSceneMouseEvent>
54 struct PolyLine::Private
59 Drawing::Tool::Private::ContourEditor
*editor
;
61 QPainterPath lastPart
;
63 YAMF::Item::Path
*item
;
64 PaintArea
* paintArea
;
67 QGraphicsLineItem
*line1
, *line2
;
69 QGraphicsPathItem
*line3
;
75 PolyLine::PolyLine(QObject
*parent
): AbstractTool(parent
), d(new Private
)
82 d
->line1
= new QGraphicsLineItem(0,0,0,0);
83 d
->line1
->setPen ( QPen(Qt::red
) );
84 d
->line2
= new QGraphicsLineItem(0,0,0,0);
85 d
->line2
->setPen ( QPen(Qt::green
) );
87 d
->line3
= new QGraphicsPathItem();
89 d
->action
= new DGui::Action( DGui::IconLoader::self()->load("draw-path.svg"), tr("Poly line"), this);
90 d
->action
->setShortcut( QKeySequence(tr("")) );
99 void PolyLine::init(Photogram
*photogram
)
103 foreach(QGraphicsView
*view
, photogram
->views() )
105 view
->setDragMode ( QGraphicsView::NoDrag
);
107 Q_CHECK_PTR(view
->scene());
108 if ( QGraphicsScene
*sscene
= qobject_cast
<QGraphicsScene
*>(view
->scene()) )
110 foreach(QGraphicsItem
*item
, sscene
->items() )
112 item
->setFlag(QGraphicsItem::ItemIsSelectable
, false);
113 item
->setFlag(QGraphicsItem::ItemIsMovable
, false);
115 sscene
->addItem( d
->line1
);
116 sscene
->addItem( d
->line2
);
121 QString
PolyLine::id() const
123 return tr("PolyLine");
126 void PolyLine::press(const QGraphicsSceneMouseEvent
*input
, PaintArea
*const paintArea
)
128 d
->paintArea
= paintArea
;
129 QGraphicsScene
*scene
= paintArea
->scene();
130 if(scene
->items().contains(d
->line3
))
132 scene
->removeItem(d
->line3
);
135 BrushManager
*brushManager
= paintArea
->brushManager();
137 scene
->clearSelection();
141 d
->path
= QPainterPath();
142 d
->path
.moveTo(input
->scenePos());
144 d
->item
= new YAMF::Item::Path();
146 d
->editor
= new Drawing::Tool::Private::ContourEditor(d
->item
, scene
);
147 connect(d
->editor
, SIGNAL(nodeClicked()), this, SLOT(nodeChanged()));
148 scene
->addItem( d
->item
);
160 d
->path
.cubicTo(d
->center
, d
->center
, input
->scenePos());
165 d
->path
.cubicTo(d
->center
, d
->right
, input
->scenePos());
169 d
->center
= input
->scenePos();
171 d
->item
->setPen( brushManager
->pen() );
174 void PolyLine::move(const QGraphicsSceneMouseEvent
*input
, PaintArea
*const paintArea
)
176 QGraphicsScene
*scene
= paintArea
->scene();
179 if(input
->buttons() == Qt::NoButton
)
181 QPainterPath lastPart
;
183 lastPart
.moveTo(d
->center
);
187 // lastPart.lineTo(input->scenePos());
188 lastPart
.cubicTo(d
->center
, d
->center
, input
->scenePos());
192 lastPart
.cubicTo(d
->center
, d
->right
, input
->scenePos());
195 d
->line3
->setPath(lastPart
);
196 if(!scene
->items().contains(d
->line3
))
198 scene
->addItem(d
->line3
);
201 if(!scene
->items().contains(d
->line1
))
203 scene
->addItem( d
->line1
);
205 if(!scene
->items().contains(d
->line2
))
207 scene
->addItem( d
->line2
);
210 else if(d
->editor
&& d
->editor
->isSelected())
212 d
->path
= d
->item
->path();
214 else if(input
->buttons() == Qt::LeftButton
)
216 paintArea
->setDragMode(QGraphicsView::NoDrag
);
221 d
->right
= input
->scenePos();
223 d
->line2
->setLine(QLineF(d
->right
, d
->center
));
224 if(!scene
->items().contains(d
->line2
))
226 scene
->addItem( d
->line2
);
232 int index
= d
->path
.elementCount()-3;
234 if( d
->path
.elementAt(index
).type
== QPainterPath::CurveToElement
)
238 QPointF point
= d
->path
.elementAt(index
+1);
239 d
->path
.setElementPositionAt(index
, point
.x(), point
.y() );
242 QPointF mirror
= d
->center
- ( input
->scenePos() - d
->center
);
244 d
->path
.setElementPositionAt(index
+1, mirror
.x(), mirror
.y());
246 d
->line1
->setLine(QLineF(mirror
, d
->center
));
247 d
->line2
->setLine(QLineF(d
->right
, d
->center
));
250 if(!scene
->items().contains(d
->line1
))
252 scene
->addItem( d
->line1
);
254 if(!scene
->items().contains(d
->line2
))
256 scene
->addItem( d
->line2
);
261 d
->right
= input
->scenePos();
262 d
->item
->setPath(d
->path
);
270 void PolyLine::release(const QGraphicsSceneMouseEvent
*input
, PaintArea
*const paintArea
)
274 d
->editor
->expandAllNodes ();
279 paintArea
->currentFrame()->addItem(d
->item
);
281 else if(!d
->editor
->isSelected())
283 int position
= paintArea
->currentFrame()->visualIndexOf(d
->item
);
287 QPainterPath path
= d
->item
->path();
288 d
->editor
->restore();
289 paintArea
->addCommand(new Command::EditNodesItem(d
->item
, d
->path
));
295 void PolyLine::doubleClick(const QGraphicsSceneMouseEvent
*input
, PaintArea
*const paintArea
)
303 DGui::Action
*PolyLine::action() const
308 int PolyLine::type() const
310 return AbstractTool::Brush
;
313 void PolyLine::aboutToChangeTool()
318 void PolyLine::photogramChanged(Photogram
*const photogram
)
324 // d->path = d->item->path();
325 // d->editor->setItem(d->item);
326 // d->editor->show();
327 // d->editor->expandAllNodes();
328 int size
= d
->item
->path().elementCount();
331 d
->center
= d
->item
->path().elementAt(size
-1);
336 void PolyLine::endItem()
340 d
->path
= QPainterPath();
347 void PolyLine::nodeChanged()
352 int position
= d
->paintArea
->currentFrame()->visualIndexOf(d
->item
);
357 int size
= d
->item
->path().elementCount();
360 d
->center
= d
->item
->path().elementAt(size
-1);
363 d
->path
= d
->item
->path();
365 d
->editor
->restore();
366 d
->paintArea
->addCommand(new Command::EditNodesItem(d
->item
, d
->path
));