]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawarc.cpp
Scrubbed out all references to RS2::qtToRsButton(). Gone!
[architektonas] / src / actions / rs_actiondrawarc.cpp
1 // rs_actiondrawarc.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/03/2010  Added this text. :-)
13 //
14
15 #include "rs_actiondrawarc.h"
16
17 #include "commands.h"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer & container, RS_GraphicView & graphicView):
23         RS_PreviewActionInterface("Draw arcs", container, graphicView)
24 {
25         reset();
26 }
27
28 RS_ActionDrawArc::~RS_ActionDrawArc()
29 {
30 }
31
32 RS2::ActionType RS_ActionDrawArc::rtti()
33 {
34         return RS2::ActionDrawArc;
35 }
36
37 void RS_ActionDrawArc::reset()
38 {
39         //bool rev = data.reversed;
40
41         if (data.reversed)
42                 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
43         else
44                 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
45 }
46
47 void RS_ActionDrawArc::init(int status)
48 {
49         RS_PreviewActionInterface::init(status);
50         reset();
51 }
52
53 void RS_ActionDrawArc::trigger()
54 {
55         RS_PreviewActionInterface::trigger();
56
57         RS_Arc * arc = new RS_Arc(container, data);
58         arc->setLayerToActive();
59         arc->setPenToActive();
60         container->addEntity(arc);
61
62         // upd. undo list:
63         if (document != NULL)
64         {
65                 document->startUndoCycle();
66                 document->addUndoable(arc);
67                 document->endUndoCycle();
68         }
69
70         deleteSnapper();
71         graphicView->moveRelativeZero(Vector(0.0, 0.0));
72         graphicView->drawEntity(arc);
73         graphicView->moveRelativeZero(arc->getCenter());
74         drawSnapper();
75
76         setStatus(SetCenter);
77         reset();
78
79         RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d", arc->getId());
80 }
81
82 void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
83 {
84         RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
85         Vector mouse = snapPoint(e);
86
87         switch (getStatus())
88         {
89         case SetCenter:
90                 data.center = mouse;
91                 break;
92
93         case SetRadius:
94
95                 if (data.center.valid)
96                 {
97                         data.radius = data.center.distanceTo(mouse);
98                         deletePreview();
99                         clearPreview();
100                         preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
101                         drawPreview();
102                 }
103                 break;
104
105         case SetAngle1:
106                 data.angle1 = data.center.angleTo(mouse);
107
108                 if (data.reversed)
109                         data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
110                 else
111                         data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
112
113                 deletePreview();
114                 clearPreview();
115                 preview->addEntity(new RS_Arc(preview, data));
116                 drawPreview();
117                 break;
118
119         case SetAngle2:
120                 data.angle2 = data.center.angleTo(mouse);
121                 deletePreview();
122                 clearPreview();
123                 preview->addEntity(new RS_Arc(preview, data));
124                 drawPreview();
125                 break;
126
127         case SetIncAngle:
128                 data.angle2 = data.angle1 + data.center.angleTo(mouse);
129                 deletePreview();
130                 clearPreview();
131                 preview->addEntity(new RS_Arc(preview, data));
132                 drawPreview();
133                 break;
134
135         case SetChordLength:
136         {
137                 double x = data.center.distanceTo(mouse);
138
139                 if (fabs(x / (2 * data.radius)) <= 1.0)
140                 {
141                         data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
142                         deletePreview();
143                         clearPreview();
144                         preview->addEntity(new RS_Arc(preview, data));
145                         drawPreview();
146                 }
147         }
148         break;
149
150         default:
151                 break;
152         }
153
154         RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
155 }
156
157 void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
158 {
159         if (e->button() == Qt::LeftButton)
160         {
161                 Vector ce(snapPoint(e));
162                 coordinateEvent(&ce);
163         }
164         else if (e->button() == Qt::RightButton)
165         {
166                 deletePreview();
167                 deleteSnapper();
168                 init(getStatus() - 1);
169         }
170 }
171
172 void RS_ActionDrawArc::coordinateEvent(Vector * e)
173 {
174         if (e == NULL)
175                 return;
176
177         Vector mouse = *e;
178
179         switch (getStatus())
180         {
181         case SetCenter:
182                 data.center = mouse;
183                 graphicView->moveRelativeZero(mouse);
184                 //deleteSnapper();
185                 setStatus(SetRadius);
186                 break;
187
188         case SetRadius:
189
190                 if (data.center.valid)
191                         data.radius = data.center.distanceTo(mouse);
192
193                 setStatus(SetAngle1);
194                 break;
195
196         case SetAngle1:
197                 data.angle1 = data.center.angleTo(mouse);
198                 setStatus(SetAngle2);
199                 break;
200
201         case SetAngle2:
202                 data.angle2 = data.center.angleTo(mouse);
203                 trigger();
204                 break;
205
206         case SetIncAngle:
207                 data.angle2 = data.angle1 + data.center.angleTo(mouse);
208                 trigger();
209                 break;
210
211         case SetChordLength:
212         {
213                 double x = data.center.distanceTo(mouse);
214
215                 if (fabs(x / (2 * data.radius)) <= 1.0)
216                 {
217                         data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
218                         trigger();
219                 }
220         }
221         break;
222
223         default:
224                 break;
225         }
226 }
227
228 void RS_ActionDrawArc::commandEvent(RS_CommandEvent * e)
229 {
230         QString c = e->getCommand().toLower();
231
232         if (RS_COMMANDS->checkCommand("help", c))
233         {
234                 if (RS_DIALOGFACTORY != NULL)
235                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
236                                 + getAvailableCommands().join(", "));
237                 return;
238         }
239
240         if (RS_COMMANDS->checkCommand("reversed", c))
241         {
242                 e->accept();
243                 setReversed(!isReversed());
244
245                 if (RS_DIALOGFACTORY != NULL)
246                         RS_DIALOGFACTORY->requestOptions(this, true, true);
247                 return;
248         }
249
250         switch (getStatus())
251         {
252         case SetRadius: {
253                 bool ok;
254                 double r = RS_Math::eval(c, &ok);
255
256                 if (ok == true)
257                 {
258                         data.radius = r;
259                         setStatus(SetAngle1);
260                 }
261                 else if (RS_DIALOGFACTORY != NULL)
262                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
263
264         }
265         break;
266
267         case SetAngle1: {
268                 bool ok;
269                 double a = RS_Math::eval(c, &ok);
270
271                 if (ok == true)
272                 {
273                         data.angle1 = RS_Math::deg2rad(a);
274                         setStatus(SetAngle2);
275                 }
276                 else if (RS_DIALOGFACTORY != NULL)
277                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
278
279         }
280         break;
281
282         case SetAngle2:
283
284                 if (RS_COMMANDS->checkCommand("angle", c))
285                         setStatus(SetIncAngle);
286                 else if (RS_COMMANDS->checkCommand("chord length", c))
287                         setStatus(SetChordLength);
288                 else
289                 {
290                         bool ok;
291                         double a = RS_Math::eval(c, &ok);
292
293                         if (ok == true)
294                         {
295                                 data.angle2 = RS_Math::deg2rad(a);
296                                 trigger();
297                         }
298                         else if (RS_DIALOGFACTORY != NULL)
299                                 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
300
301                 }
302                 break;
303
304         case SetIncAngle: {
305                 bool ok;
306                 double a = RS_Math::eval(c, &ok);
307
308                 if (ok == true)
309                 {
310                         data.angle2 = data.angle1 + RS_Math::deg2rad(a);
311                         trigger();
312                 }
313                 else if (RS_DIALOGFACTORY != NULL)
314                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
315
316         }
317         break;
318
319         case SetChordLength: {
320                 bool ok;
321                 double l = RS_Math::eval(c, &ok);
322
323                 if (ok == true)
324                 {
325                         if (fabs(l / (2 * data.radius)) <= 1.0)
326                         {
327                                 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
328                                 trigger();
329                         }
330                         else if (RS_DIALOGFACTORY != NULL)
331                                 RS_DIALOGFACTORY->commandMessage(
332                                         tr("Not a valid chord length"));
333
334                 }
335                 else if (RS_DIALOGFACTORY != NULL)
336                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
337
338         }
339         break;
340
341         default:
342                 break;
343         }
344 }
345
346 QStringList RS_ActionDrawArc::getAvailableCommands()
347 {
348         QStringList cmd;
349         cmd += RS_COMMANDS->command("reversed");
350         return cmd;
351 }
352
353 void RS_ActionDrawArc::updateMouseButtonHints()
354 {
355         if (RS_DIALOGFACTORY != NULL)
356         {
357                 switch (getStatus())
358                 {
359                 case SetCenter:
360                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
361                         break;
362
363                 case SetRadius:
364                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
365                         break;
366
367                 case SetAngle1:
368                         RS_DIALOGFACTORY->updateMouseWidget(
369                                 tr("Specify start angle:"), tr("Back"));
370                         break;
371
372                 case SetAngle2:
373                         RS_DIALOGFACTORY->updateMouseWidget(
374                                 tr("Specify end angle or [Angle/chord Length]"),
375                                 tr("Back"));
376                         break;
377
378                 case SetIncAngle:
379                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
380                                 tr("Back"));
381                         break;
382
383                 case SetChordLength:
384                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
385                                 tr("Back"));
386                         break;
387
388                 default:
389                         RS_DIALOGFACTORY->updateMouseWidget("", "");
390                         break;
391                 }
392         }
393 }
394
395 void RS_ActionDrawArc::showOptions()
396 {
397         RS_ActionInterface::showOptions();
398
399         if (RS_DIALOGFACTORY != NULL)
400                 RS_DIALOGFACTORY->requestOptions(this, true);
401 }
402
403 void RS_ActionDrawArc::hideOptions()
404 {
405         RS_ActionInterface::hideOptions();
406
407         if (RS_DIALOGFACTORY != NULL)
408                 RS_DIALOGFACTORY->requestOptions(this, false);
409 }
410
411 void RS_ActionDrawArc::updateMouseCursor()
412 {
413         graphicView->setMouseCursor(RS2::CadCursor);
414 }
415
416 void RS_ActionDrawArc::updateToolBar()
417 {
418         if (RS_DIALOGFACTORY == NULL)
419                 return;
420
421         if (!isFinished())
422                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
423         else
424                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
425 }
426
427 bool RS_ActionDrawArc::isReversed()
428 {
429         return data.reversed;
430 }
431
432 void RS_ActionDrawArc::setReversed(bool r)
433 {
434         data.reversed = r;
435 }
436