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