]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawellipseaxis.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / actions / actiondrawellipseaxis.cpp
1 // actiondrawellipseaxis.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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/22/2010  Added this text. :-)
15 //
16
17 #include "actiondrawellipseaxis.h"
18
19 #include "commandevent.h"
20 #include "debug.h"
21 #include "dialogfactory.h"
22 #include "graphicview.h"
23 #include "preview.h"
24
25 /**
26  * Constructor.
27  *
28  * @param isArc true if this action will produce an ellipse arc.
29  *              false if it will produce a full ellipse.
30  */
31 ActionDrawEllipseAxis::ActionDrawEllipseAxis(EntityContainer & container, GraphicView & graphicView, bool isArc): ActionInterface("Draw ellipse with axis",
32                 container, graphicView)
33 {
34         this->isArc = isArc;
35         center = Vector(false);
36         major = Vector(false);
37         ratio = 0.5;
38         angle1 = 0.0;
39         angle2 = 2 * M_PI;
40 }
41
42 ActionDrawEllipseAxis::~ActionDrawEllipseAxis()
43 {
44 }
45
46 void ActionDrawEllipseAxis::init(int status)
47 {
48         ActionInterface::init(status);
49
50         if (status == SetCenter)
51                 center = Vector(false);
52
53         if (status <= SetMajor)
54                 major = Vector(false);
55
56         if (status <= SetMinor)
57                 ratio = 0.5;
58
59         if (status <= SetAngle1)
60                 angle1 = 0.0;
61
62         if (status <= SetAngle2)
63                 angle2 = 2 * M_PI;
64 }
65
66 void ActionDrawEllipseAxis::trigger()
67 {
68         ActionInterface::trigger();
69
70         EllipseData ellipseData(center, major, ratio, angle1, angle2, false);
71         Ellipse * ellipse = new Ellipse(container, ellipseData);
72         ellipse->setLayerToActive();
73         ellipse->setPenToActive();
74
75         container->addEntity(ellipse);
76
77         // upd. undo list:
78         if (document != NULL)
79         {
80                 document->startUndoCycle();
81                 document->addUndoable(ellipse);
82                 document->endUndoCycle();
83         }
84
85         deleteSnapper();
86         Vector rz = graphicView->getRelativeZero();
87         graphicView->moveRelativeZero(Vector(0.0, 0.0));
88         graphicView->drawEntity(ellipse);
89         graphicView->moveRelativeZero(rz);
90         drawSnapper();
91
92         setStatus(SetCenter);
93
94         DEBUG->print("ActionDrawEllipseAxis::trigger():"
95                 " entity added: %d", ellipse->getId());
96 }
97
98 void ActionDrawEllipseAxis::mouseMoveEvent(QMouseEvent * e)
99 {
100         DEBUG->print("ActionDrawEllipseAxis::mouseMoveEvent begin");
101
102         Vector mouse = snapPoint(e);
103
104         switch (getStatus())
105         {
106         case SetCenter:
107                 break;
108
109         case SetMajor:
110
111                 if (center.valid)
112                 {
113                         deletePreview();
114                         clearPreview();
115                         EllipseData ed(center, mouse - center, 0.5, 0.0, 2 * M_PI, false);
116 //                      preview->addEntity(new Ellipse(preview, ed));
117                         drawPreview();
118                 }
119                 break;
120
121         case SetMinor:
122
123                 if (center.valid && major.valid)
124                 {
125                         deletePreview();
126                         clearPreview();
127                         Line line(NULL, LineData(center - major, center + major));
128                         double d = line.getDistanceToPoint(mouse);
129                         ratio = d / (line.getLength() / 2);
130                         EllipseData ed(center, major, ratio, 0.0, 2 * M_PI, false);
131 //                      preview->addEntity(new Ellipse(preview, ed));
132                         drawPreview();
133                 }
134                 break;
135
136         case SetAngle1:
137
138                 if (center.valid && major.valid)
139                 {
140                         deletePreview();
141                         clearPreview();
142
143                         //angle1 = center.angleTo(mouse);
144
145                         Vector m = mouse;
146                         m.rotate(center, -major.angle());
147                         Vector v = m - center;
148                         v.scale(Vector(1.0, 1.0 / ratio));
149                         angle1 = v.angle(); // + major.angle();
150
151 //                      preview->addEntity(new Line(preview, LineData(center, mouse)));
152
153                         EllipseData ed(center, major, ratio, angle1, angle1 + 1.0, false);
154 //                      preview->addEntity(new Ellipse(preview, ed));
155                         drawPreview();
156                 }
157                 break;
158
159         case SetAngle2:
160
161                 if (center.valid && major.valid)
162                 {
163                         deletePreview();
164                         clearPreview();
165                         //angle2 = center.angleTo(mouse);
166
167                         Vector m = mouse;
168                         m.rotate(center, -major.angle());
169                         Vector v = m - center;
170                         v.scale(Vector(1.0, 1.0 / ratio));
171                         angle2 = v.angle(); // + major.angle();
172
173 //                      preview->addEntity(new Line(preview, LineData(center, mouse)));
174
175                         EllipseData ed(center, major, ratio, angle1, angle2, false);
176 //                      preview->addEntity(new Ellipse(preview, ed));
177                         drawPreview();
178                 }
179
180         default:
181                 break;
182         }
183
184         DEBUG->print("ActionDrawEllipseAxis::mouseMoveEvent end");
185 }
186
187 void ActionDrawEllipseAxis::mouseReleaseEvent(QMouseEvent * e)
188 {
189         // Proceed to next status
190         if (e->button() == Qt::LeftButton)
191         {
192                 Vector ce(snapPoint(e));
193                 coordinateEvent(&ce);
194         }
195         // Return to last status:
196         else if (e->button() == Qt::RightButton)
197         {
198                 deletePreview();
199                 deleteSnapper();
200                 init(getStatus() - 1);
201         }
202 }
203
204 void ActionDrawEllipseAxis::coordinateEvent(Vector * e)
205 {
206         if (e == NULL)
207                 return;
208
209         Vector mouse = *e;
210
211         switch (getStatus())
212         {
213         case SetCenter:
214                 center = mouse;
215                 graphicView->moveRelativeZero(mouse);
216                 setStatus(SetMajor);
217                 break;
218
219         case SetMajor:
220                 major = mouse - center;
221                 setStatus(SetMinor);
222                 break;
223
224         case SetMinor:
225         {
226                 Line line(NULL, LineData(center - major, center + major));
227                 double d = line.getDistanceToPoint(mouse);
228                 ratio = d / (line.getLength() / 2);
229
230                 if (!isArc)
231                 {
232                         trigger();
233                         setStatus(SetCenter);
234                 }
235                 else
236                         setStatus(SetAngle1);
237         }
238         break;
239
240         case SetAngle1:
241         {
242                 //angle1 = center.angleTo(mouse);
243                 Vector m = mouse;
244                 m.rotate(center, -major.angle());
245                 Vector v = m - center;
246                 v.scale(Vector(1.0, 1.0 / ratio));
247                 angle1 = v.angle();
248                 setStatus(SetAngle2);
249         }
250         break;
251
252         case SetAngle2:
253         {
254                 //angle2 = center.angleTo(mouse);
255                 Vector m = mouse;
256                 m.rotate(center, -major.angle());
257                 Vector v = m - center;
258                 v.scale(Vector(1.0, 1.0 / ratio));
259                 angle2 = v.angle();
260                 trigger();
261         }
262         break;
263
264         default:
265                 break;
266         }
267 }
268
269 void ActionDrawEllipseAxis::commandEvent(CommandEvent * e)
270 {
271         QString c = e->getCommand().toLower();
272
273         if (checkCommand("help", c))
274         {
275                 if (DIALOGFACTORY != NULL)
276                         DIALOGFACTORY->commandMessage(msgAvailableCommands()
277                                 + getAvailableCommands().join(", "));
278                 return;
279         }
280
281         switch (getStatus())
282         {
283         case SetMinor: {
284                 bool ok;
285                 double m = Math::eval(c, &ok);
286
287                 if (ok == true)
288                 {
289                         ratio = m / major.magnitude();
290
291                         if (!isArc)
292                                 trigger();
293                         else
294                                 setStatus(SetAngle1);
295                 }
296                 else if (DIALOGFACTORY != NULL)
297                         DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
298
299         }
300         break;
301
302         case SetAngle1: {
303                 bool ok;
304                 double a = Math::eval(c, &ok);
305
306                 if (ok == true)
307                 {
308                         angle1 = Math::deg2rad(a);
309                         setStatus(SetAngle2);
310                 }
311                 else if (DIALOGFACTORY != NULL)
312                         DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
313
314         }
315         break;
316
317         case SetAngle2: {
318                 bool ok;
319                 double a = Math::eval(c, &ok);
320
321                 if (ok == true)
322                 {
323                         angle2 = Math::deg2rad(a);
324                         trigger();
325                 }
326                 else if (DIALOGFACTORY != NULL)
327                         DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
328
329         }
330         break;
331
332         default:
333                 break;
334         }
335 }
336
337 QStringList ActionDrawEllipseAxis::getAvailableCommands()
338 {
339         QStringList cmd;
340         return cmd;
341 }
342
343 void ActionDrawEllipseAxis::updateMouseButtonHints()
344 {
345         if (DIALOGFACTORY != NULL)
346         {
347                 switch (getStatus())
348                 {
349                 case SetCenter:
350                         DIALOGFACTORY->updateMouseWidget(tr("Specify ellipse center"),
351                                 tr("Cancel"));
352                         break;
353
354                 case SetMajor:
355                         DIALOGFACTORY->updateMouseWidget(tr("Specify endpoint of major axis"),
356                                 tr("Back"));
357                         break;
358
359                 case SetMinor:
360                         DIALOGFACTORY->updateMouseWidget(
361                                 tr("Specify endpoint or length of minor axis:"),
362                                 tr("Back"));
363                         break;
364
365                 case SetAngle1:
366                         DIALOGFACTORY->updateMouseWidget(tr("Specify start angle"),
367                                 tr("Back"));
368                         break;
369
370                 case SetAngle2:
371                         DIALOGFACTORY->updateMouseWidget(tr("Specify end angle"),
372                                 tr("Back"));
373                         break;
374
375                 default:
376                         DIALOGFACTORY->updateMouseWidget("", "");
377                         break;
378                 }
379         }
380 }
381
382 void ActionDrawEllipseAxis::updateMouseCursor()
383 {
384         graphicView->setMouseCursor(RS2::CadCursor);
385 }
386
387 void ActionDrawEllipseAxis::updateToolBar()
388 {
389         if (DIALOGFACTORY)
390         {
391                 if (!isFinished())
392                         DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
393                 else
394                         DIALOGFACTORY->requestToolBar(RS2::ToolBarEllipses);
395         }
396 }