]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawspline.cpp
faa11ebf88e55bd2f800f73c75345cd615fef61c
[architektonas] / src / actions / rs_actiondrawspline.cpp
1 // rs_actiondrawspline.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  06/04/2010  Added this text. :-)
13 //
14
15 #include "rs_actiondrawspline.h"
16
17 #include "commands.h"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawSpline::RS_ActionDrawSpline(RS_EntityContainer & container, RS_GraphicView & graphicView):
23         RS_PreviewActionInterface("Draw splines", container, graphicView)
24 {
25         reset();
26 #warning "!!! Need to port setAutoDelete() behaviour from Qt3 to Qt4 !!!"
27 //      history.setAutoDelete(true);
28         data = RS_SplineData(3, false);
29         //bHistory.setAutoDelete(true);
30 }
31
32 RS_ActionDrawSpline::~RS_ActionDrawSpline()
33 {
34 }
35
36 /*virtual*/ RS2::ActionType RS_ActionDrawSpline::rtti()
37 {
38         return RS2::ActionDrawSpline;
39 }
40
41 void RS_ActionDrawSpline::reset()
42 {
43         spline = NULL;
44         //start = Vector(false);
45         history.clear();
46         //bHistory.clear();
47 }
48
49 void RS_ActionDrawSpline::init(int status)
50 {
51         RS_PreviewActionInterface::init(status);
52
53         reset();
54 }
55
56 void RS_ActionDrawSpline::trigger()
57 {
58         RS_PreviewActionInterface::trigger();
59
60         if (spline == NULL)
61                 return;
62
63         // add the entity
64         //RS_Spline* spline = new RS_Spline(container, data);
65         spline->setLayerToActive();
66         spline->setPenToActive();
67         spline->update();
68         container->addEntity(spline);
69
70         // upd. undo list:
71         if (document != NULL)
72         {
73                 document->startUndoCycle();
74                 document->addUndoable(spline);
75                 document->endUndoCycle();
76         }
77
78         // upd view
79         deleteSnapper();
80         Vector r = graphicView->getRelativeZero();
81         graphicView->moveRelativeZero(Vector(0.0, 0.0));
82         graphicView->drawEntity(spline);
83         graphicView->moveRelativeZero(r);
84         drawSnapper();
85         RS_DEBUG->print("RS_ActionDrawSpline::trigger(): spline added: %d", spline->getId());
86
87         spline = NULL;
88         //history.clear();
89 }
90
91 void RS_ActionDrawSpline::mouseMoveEvent(QMouseEvent * e)
92 {
93         RS_DEBUG->print("RS_ActionDrawSpline::mouseMoveEvent begin");
94
95         Vector mouse = snapPoint(e);
96
97         if (getStatus() == SetNextPoint && spline != NULL /*&& point.valid*/)
98         {
99                 deletePreview();
100                 clearPreview();
101
102                 RS_Spline * tmpSpline = (RS_Spline *)spline->clone();
103                 tmpSpline->addControlPoint(mouse);
104                 tmpSpline->update();
105                 preview->addEntity(tmpSpline);
106
107                 QList<Vector> cpts = tmpSpline->getControlPoints();
108                 QList<Vector>::iterator it;
109
110                 for(it = cpts.begin(); it != cpts.end(); ++it)
111                         preview->addEntity(new RS_Point(preview, RS_PointData(*it)));
112
113                 drawPreview();
114         }
115
116         RS_DEBUG->print("RS_ActionDrawSpline::mouseMoveEvent end");
117 }
118
119 void RS_ActionDrawSpline::mouseReleaseEvent(QMouseEvent * e)
120 {
121         if (e->button() == Qt::LeftButton)
122         {
123                 Vector ce(snapPoint(e));
124                 coordinateEvent(&ce);
125         }
126         else if (e->button() == Qt::RightButton)
127         {
128                 if (getStatus() == SetNextPoint)
129                         trigger();
130
131                 deletePreview();
132                 clearPreview();
133                 deleteSnapper();
134                 init(getStatus() - 1);
135         }
136 }
137
138 void RS_ActionDrawSpline::coordinateEvent(Vector * e)
139 {
140         if (e == NULL)
141                 return;
142
143         Vector mouse = *e;
144
145         switch (getStatus())
146         {
147         case SetStartpoint:
148                 //data.startpoint = mouse;
149                 //point = mouse;
150                 history.clear();
151                 history.append(new Vector(mouse));
152
153                 if (spline == NULL)
154                 {
155                         spline = new RS_Spline(container, data);
156                         spline->addControlPoint(mouse);
157                 }
158
159                 //bHistory.clear();
160                 //bHistory.append(new double(0.0));
161                 //start = mouse;
162                 setStatus(SetNextPoint);
163                 graphicView->moveRelativeZero(mouse);
164                 updateMouseButtonHints();
165                 break;
166
167         case SetNextPoint:
168                 graphicView->moveRelativeZero(mouse);
169                 //point = mouse;
170                 history.append(new Vector(mouse));
171                 //bHistory.append(new double(0.0));
172
173                 if (spline != NULL)
174                 {
175                         //graphicView->deleteEntity(spline);
176                         spline->addControlPoint(mouse);
177                         //spline->setEndpoint(mouse);
178                         //if (spline->count()==1) {
179                         //spline->setLayerToActive();
180                         //spline->setPenToActive();
181                         //container->addEntity(spline);
182                         //}
183                         deletePreview();
184                         clearPreview();
185                         deleteSnapper();
186                         //graphicView->drawEntity(spline);
187                         drawSnapper();
188                 }
189
190                 //trigger();
191                 //data.startpoint = data.endpoint;
192                 updateMouseButtonHints();
193                 //graphicView->moveRelativeZero(mouse);
194                 break;
195
196         default:
197                 break;
198         }
199 }
200
201 void RS_ActionDrawSpline::commandEvent(RS_CommandEvent * e)
202 {
203         QString c = e->getCommand().toLower();
204
205         switch (getStatus())
206         {
207         case SetStartpoint:
208
209                 if (checkCommand("help", c))
210                 {
211                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
212                                 + getAvailableCommands().join(", "));
213                         return;
214                 }
215                 break;
216
217         case SetNextPoint:
218                 /*if (checkCommand("close", c)) {
219                     close();
220                     updateMouseButtonHints();
221                     return;
222                    }*/
223
224                 if (checkCommand("undo", c))
225                 {
226                         undo();
227                         updateMouseButtonHints();
228                         return;
229                 }
230                 break;
231
232         default:
233                 break;
234         }
235 }
236
237 QStringList RS_ActionDrawSpline::getAvailableCommands()
238 {
239         QStringList cmd;
240
241         switch (getStatus())
242         {
243         case SetStartpoint:
244                 break;
245
246         case SetNextPoint:
247
248                 if (history.count() >= 2)
249                         cmd += command("undo");
250
251
252                 if (history.count() >= 3)
253                         cmd += command("close");
254                 break;
255
256         default:
257                 break;
258         }
259
260         return cmd;
261 }
262
263 void RS_ActionDrawSpline::updateMouseButtonHints()
264 {
265         switch (getStatus())
266         {
267         case SetStartpoint:
268                 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first control point"),
269                         tr("Cancel"));
270                 break;
271
272         case SetNextPoint: {
273                 QString msg = "";
274
275                 if (history.count() >= 3)
276                 {
277                         msg += RS_COMMANDS->command("close");
278                         msg += "/";
279                 }
280
281                 if (history.count() >= 2)
282                         msg += RS_COMMANDS->command("undo");
283
284                 if (history.count() >= 2)
285                         RS_DIALOGFACTORY->updateMouseWidget(
286                                 tr("Specify next control point or [%1]").arg(msg),
287                                 tr("Back"));
288                 else
289                         RS_DIALOGFACTORY->updateMouseWidget(
290                                 tr("Specify next control point"),
291                                 tr("Back"));
292         }
293         break;
294
295         default:
296                 RS_DIALOGFACTORY->updateMouseWidget("", "");
297                 break;
298         }
299 }
300
301 void RS_ActionDrawSpline::showOptions()
302 {
303         RS_ActionInterface::showOptions();
304
305         RS_DIALOGFACTORY->requestOptions(this, true);
306 }
307
308 void RS_ActionDrawSpline::hideOptions()
309 {
310         RS_ActionInterface::hideOptions();
311
312         RS_DIALOGFACTORY->requestOptions(this, false);
313 }
314
315 void RS_ActionDrawSpline::updateMouseCursor()
316 {
317         graphicView->setMouseCursor(RS2::CadCursor);
318 }
319
320 void RS_ActionDrawSpline::updateToolBar()
321 {
322         if (!isFinished())
323                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
324         else
325                 //RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSplines);
326                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarMain);
327 }
328
329 /*
330    void RS_ActionDrawSpline::close() {
331     if (history.count()>2 && start.valid) {
332         //data.endpoint = start;
333         //trigger();
334                 if (spline!=NULL) {
335                         Vector e(spline->getStartpoint());
336                         coordinateEvent(&e);
337                 }
338                 trigger();
339         setStatus(SetStartpoint);
340         graphicView->moveRelativeZero(start);
341     } else {
342         RS_DIALOGFACTORY->commandMessage(
343             tr("Cannot close sequence of lines: "
344                "Not enough entities defined yet."));
345     }
346    }
347  */
348
349 void RS_ActionDrawSpline::undo()
350 {
351         if (history.count() > 1)
352         {
353                 history.removeLast();
354                 //bHistory.removeLast();
355                 deletePreview();
356                 clearPreview();
357
358                 //graphicView->setCurrentAction(
359                 //    new RS_ActionEditUndo(true, *container, *graphicView));
360                 if (history.last() != NULL)
361                 {
362                         //point = *history.last();
363                 }
364
365                 if (spline != NULL)
366                 {
367                         spline->removeLastControlPoint();
368                         Vector * v = history.last();
369
370                         if (v != NULL)
371                                 graphicView->moveRelativeZero(*v);
372                         graphicView->redraw();
373                 }
374         }
375         else
376                 RS_DIALOGFACTORY->commandMessage(
377                         tr("Cannot undo: "
378                                 "Not enough entities defined yet."));
379 }
380
381 void RS_ActionDrawSpline::setDegree(int deg)
382 {
383         data.degree = deg;
384
385         if (spline != NULL)
386                 spline->setDegree(deg);
387 }
388
389 int RS_ActionDrawSpline::getDegree()
390 {
391         return data.degree;
392 }
393
394 void RS_ActionDrawSpline::setClosed(bool c)
395 {
396         data.closed = c;
397
398         if (spline != NULL)
399                 spline->setClosed(c);
400 }
401
402 bool RS_ActionDrawSpline::isClosed()
403 {
404         return data.closed;
405 }
406
407 // EOF