]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawellipseaxis.cpp
Last checkin before major refactor...
[architektonas] / src / actions / rs_actiondrawellipseaxis.cpp
1 // rs_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 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/22/2010  Added this text. :-)
13 //
14
15 #include "rs_actiondrawellipseaxis.h"
16
17 #include "rs_commandevent.h"
18 #include "rs_dialogfactory.h"
19 #include "graphicview.h"
20 #include "rs_preview.h"
21
22 /**
23  * Constructor.
24  *
25  * @param isArc true if this action will produce an ellipse arc.
26  *              false if it will produce a full ellipse.
27  */
28 RS_ActionDrawEllipseAxis::RS_ActionDrawEllipseAxis(RS_EntityContainer & container, GraphicView & graphicView, bool isArc): RS_PreviewActionInterface("Draw ellipse with axis",
29                 container, graphicView)
30 {
31         this->isArc = isArc;
32         center = Vector(false);
33         major = Vector(false);
34         ratio = 0.5;
35         angle1 = 0.0;
36         angle2 = 2 * M_PI;
37 }
38
39 RS_ActionDrawEllipseAxis::~RS_ActionDrawEllipseAxis()
40 {
41 }
42
43 void RS_ActionDrawEllipseAxis::init(int status)
44 {
45         RS_PreviewActionInterface::init(status);
46
47         if (status == SetCenter)
48                 center = Vector(false);
49
50         if (status <= SetMajor)
51                 major = Vector(false);
52
53         if (status <= SetMinor)
54                 ratio = 0.5;
55
56         if (status <= SetAngle1)
57                 angle1 = 0.0;
58
59         if (status <= SetAngle2)
60                 angle2 = 2 * M_PI;
61 }
62
63 void RS_ActionDrawEllipseAxis::trigger()
64 {
65         RS_PreviewActionInterface::trigger();
66
67         RS_EllipseData ellipseData(center, major, ratio, angle1, angle2, false);
68         RS_Ellipse * ellipse = new RS_Ellipse(container, ellipseData);
69         ellipse->setLayerToActive();
70         ellipse->setPenToActive();
71
72         container->addEntity(ellipse);
73
74         // upd. undo list:
75         if (document != NULL)
76         {
77                 document->startUndoCycle();
78                 document->addUndoable(ellipse);
79                 document->endUndoCycle();
80         }
81
82         deleteSnapper();
83         Vector rz = graphicView->getRelativeZero();
84         graphicView->moveRelativeZero(Vector(0.0, 0.0));
85         graphicView->drawEntity(ellipse);
86         graphicView->moveRelativeZero(rz);
87         drawSnapper();
88
89         setStatus(SetCenter);
90
91         RS_DEBUG->print("RS_ActionDrawEllipseAxis::trigger():"
92                 " entity added: %d", ellipse->getId());
93 }
94
95 void RS_ActionDrawEllipseAxis::mouseMoveEvent(QMouseEvent * e)
96 {
97         RS_DEBUG->print("RS_ActionDrawEllipseAxis::mouseMoveEvent begin");
98
99         Vector mouse = snapPoint(e);
100
101         switch (getStatus())
102         {
103         case SetCenter:
104                 break;
105
106         case SetMajor:
107
108                 if (center.valid)
109                 {
110                         deletePreview();
111                         clearPreview();
112                         RS_EllipseData ed(center, mouse - center, 0.5, 0.0, 2 * M_PI, false);
113                         preview->addEntity(new RS_Ellipse(preview, ed));
114                         drawPreview();
115                 }
116                 break;
117
118         case SetMinor:
119
120                 if (center.valid && major.valid)
121                 {
122                         deletePreview();
123                         clearPreview();
124                         RS_Line line(NULL, RS_LineData(center - major, center + major));
125                         double d = line.getDistanceToPoint(mouse);
126                         ratio = d / (line.getLength() / 2);
127                         RS_EllipseData ed(center, major, ratio, 0.0, 2 * M_PI, false);
128                         preview->addEntity(new RS_Ellipse(preview, ed));
129                         drawPreview();
130                 }
131                 break;
132
133         case SetAngle1:
134
135                 if (center.valid && major.valid)
136                 {
137                         deletePreview();
138                         clearPreview();
139
140                         //angle1 = center.angleTo(mouse);
141
142                         Vector m = mouse;
143                         m.rotate(center, -major.angle());
144                         Vector v = m - center;
145                         v.scale(Vector(1.0, 1.0 / ratio));
146                         angle1 = v.angle(); // + major.angle();
147
148                         preview->addEntity(new RS_Line(preview, RS_LineData(center, mouse)));
149
150                         RS_EllipseData ed(center, major, ratio, angle1, angle1 + 1.0, false);
151                         preview->addEntity(new RS_Ellipse(preview, ed));
152                         drawPreview();
153                 }
154                 break;
155
156         case SetAngle2:
157
158                 if (center.valid && major.valid)
159                 {
160                         deletePreview();
161                         clearPreview();
162                         //angle2 = center.angleTo(mouse);
163
164                         Vector m = mouse;
165                         m.rotate(center, -major.angle());
166                         Vector v = m - center;
167                         v.scale(Vector(1.0, 1.0 / ratio));
168                         angle2 = v.angle(); // + major.angle();
169
170                         preview->addEntity(new RS_Line(preview, RS_LineData(center, mouse)));
171
172                         RS_EllipseData ed(
173                                 center, major, ratio, angle1, angle2, false);
174                         preview->addEntity(new RS_Ellipse(preview, ed));
175                         drawPreview();
176                 }
177
178         default:
179                 break;
180         }
181
182         RS_DEBUG->print("RS_ActionDrawEllipseAxis::mouseMoveEvent end");
183 }
184
185 void RS_ActionDrawEllipseAxis::mouseReleaseEvent(QMouseEvent * e)
186 {
187         // Proceed to next status
188 //      if (RS2::qtToRsButtonState(e->button())==RS2::LeftButton)
189         if (e->button() == Qt::LeftButton)
190         {
191                 Vector ce(snapPoint(e));
192                 coordinateEvent(&ce);
193         }
194         // Return to last status:
195 //      else if (RS2::qtToRsButtonState(e->button())==RS2::RightButton)
196         else if (e->button() == Qt::RightButton)
197         {
198                 deletePreview();
199                 deleteSnapper();
200                 init(getStatus() - 1);
201         }
202 }
203
204 void RS_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                 RS_Line line(NULL, RS_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 RS_ActionDrawEllipseAxis::commandEvent(RS_CommandEvent * e)
270 {
271         QString c = e->getCommand().toLower();
272
273         if (checkCommand("help", c))
274         {
275                 if (RS_DIALOGFACTORY != NULL)
276                         RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
277                                 + getAvailableCommands().join(", "));
278                 return;
279         }
280
281         switch (getStatus())
282         {
283         case SetMinor: {
284                 bool ok;
285                 double m = RS_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 (RS_DIALOGFACTORY != NULL)
297                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
298
299         }
300         break;
301
302         case SetAngle1: {
303                 bool ok;
304                 double a = RS_Math::eval(c, &ok);
305
306                 if (ok == true)
307                 {
308                         angle1 = RS_Math::deg2rad(a);
309                         setStatus(SetAngle2);
310                 }
311                 else if (RS_DIALOGFACTORY != NULL)
312                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
313
314         }
315         break;
316
317         case SetAngle2: {
318                 bool ok;
319                 double a = RS_Math::eval(c, &ok);
320
321                 if (ok == true)
322                 {
323                         angle2 = RS_Math::deg2rad(a);
324                         trigger();
325                 }
326                 else if (RS_DIALOGFACTORY != NULL)
327                         RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
328
329         }
330         break;
331
332         default:
333                 break;
334         }
335 }
336
337 QStringList RS_ActionDrawEllipseAxis::getAvailableCommands()
338 {
339         QStringList cmd;
340         return cmd;
341 }
342
343 void RS_ActionDrawEllipseAxis::updateMouseButtonHints()
344 {
345         if (RS_DIALOGFACTORY != NULL)
346         {
347                 switch (getStatus())
348                 {
349                 case SetCenter:
350                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify ellipse center"),
351                                 tr("Cancel"));
352                         break;
353
354                 case SetMajor:
355                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify endpoint of major axis"),
356                                 tr("Back"));
357                         break;
358
359                 case SetMinor:
360                         RS_DIALOGFACTORY->updateMouseWidget(
361                                 tr("Specify endpoint or length of minor axis:"),
362                                 tr("Back"));
363                         break;
364
365                 case SetAngle1:
366                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify start angle"),
367                                 tr("Back"));
368                         break;
369
370                 case SetAngle2:
371                         RS_DIALOGFACTORY->updateMouseWidget(tr("Specify end angle"),
372                                 tr("Back"));
373                         break;
374
375                 default:
376                         RS_DIALOGFACTORY->updateMouseWidget("", "");
377                         break;
378                 }
379         }
380 }
381
382 void RS_ActionDrawEllipseAxis::updateMouseCursor()
383 {
384         graphicView->setMouseCursor(RS2::CadCursor);
385 }
386
387 void RS_ActionDrawEllipseAxis::updateToolBar()
388 {
389         if (RS_DIALOGFACTORY != NULL)
390         {
391                 if (!isFinished())
392                         RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
393                 else
394                         RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarEllipses);
395         }
396 }
397
398 // EOF