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