]> Shamusworld >> Repos - architektonas/blob - src/actions/actiondrawarctangential.cpp
Last checkin before major refactor...
[architektonas] / src / actions / actiondrawarctangential.cpp
1 // actiondrawarctangential.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 "actiondrawarctangential.h"
16
17 #include "rs_commandevent.h"
18 #include "rs_dialogfactory.h"
19 #include "graphicview.h"
20 #include "rs_preview.h"
21
22 ActionDrawArcTangential::ActionDrawArcTangential(RS_EntityContainer & container, GraphicView & graphicView): ActionInterface("Draw arcs tangential",
23                 container, graphicView)
24 {
25         reset();
26 }
27
28 ActionDrawArcTangential::~ActionDrawArcTangential()
29 {
30 }
31
32 /*virtual*/ RS2::ActionType ActionDrawArcTangential::rtti()
33 {
34         return RS2::ActionDrawArcTangential;
35 }
36
37 void ActionDrawArcTangential::reset()
38 {
39         baseEntity = NULL;
40         isStartPoint = false;
41         point = Vector(false);
42 }
43
44 void ActionDrawArcTangential::init(int status)
45 {
46         ActionInterface::init(status);
47         //reset();
48 }
49
50 void ActionDrawArcTangential::trigger()
51 {
52         ActionInterface::trigger();
53
54         if (point.valid == false || baseEntity == NULL)
55         {
56                 RS_DEBUG->print("ActionDrawArcTangential::trigger: "
57                         "conditions not met");
58                 return;
59         }
60
61         preparePreview();
62         RS_Arc * arc = new RS_Arc(container, data);
63         arc->setLayerToActive();
64         arc->setPenToActive();
65         container->addEntity(arc);
66
67         // upd. undo list:
68         if (document != NULL)
69         {
70                 document->startUndoCycle();
71                 document->addUndoable(arc);
72                 document->endUndoCycle();
73         }
74
75         deleteSnapper();
76         graphicView->moveRelativeZero(Vector(0.0, 0.0));
77         graphicView->drawEntity(arc);
78         graphicView->moveRelativeZero(arc->getCenter());
79         drawSnapper();
80
81         setStatus(SetBaseEntity);
82         reset();
83 }
84
85 void ActionDrawArcTangential::preparePreview()
86 {
87         if (baseEntity != NULL && point.valid)
88         {
89                 Vector startPoint;
90                 double direction;
91
92                 if (isStartPoint)
93                 {
94                         startPoint = baseEntity->getStartpoint();
95                         direction = RS_Math::correctAngle(baseEntity->getDirection1() + M_PI);
96                 }
97                 else
98                 {
99                         startPoint = baseEntity->getEndpoint();
100                         direction = RS_Math::correctAngle(baseEntity->getDirection2() + M_PI);
101                 }
102
103                 RS_Arc arc(NULL, RS_ArcData());
104                 bool suc = arc.createFrom2PDirectionRadius(startPoint, point, direction, data.radius);
105
106                 if (suc)
107                         data = arc.getData();
108         }
109 }
110
111 void ActionDrawArcTangential::mouseMoveEvent(QMouseEvent * e)
112 {
113         switch (getStatus())
114         {
115         case SetBaseEntity:
116                 break;
117
118         case SetEndAngle:
119                 point = snapPoint(e);
120                 preparePreview();
121
122                 if (data.isValid())
123                 {
124 //                      RS_Arc * arc = new RS_Arc(preview, data);
125 //                      deletePreview();
126 //                      clearPreview();
127 //                      preview->addEntity(arc);
128 //                      drawPreview();
129                 }
130                 break;
131
132         default:
133                 break;
134         }
135 }
136
137 void ActionDrawArcTangential::mouseReleaseEvent(QMouseEvent * e)
138 {
139         if (e->button() == Qt::LeftButton)
140         {
141                 switch (getStatus())
142                 {
143                 // set base entity:
144                 case SetBaseEntity:
145                 {
146                         Vector coord = graphicView->toGraph(e->x(), e->y());
147                         RS_Entity * entity = catchEntity(coord, RS2::ResolveAll);
148
149                         if (entity != NULL)
150                         {
151                                 if (entity->isAtomic())
152                                 {
153                                         baseEntity = (RS_AtomicEntity *)entity;
154
155                                         if (baseEntity->getStartpoint().distanceTo(coord)
156                                             < baseEntity->getEndpoint().distanceTo(coord))
157                                                 isStartPoint = true;
158                                         else
159                                                 isStartPoint = false;
160                                         setStatus(SetEndAngle);
161                                         updateMouseButtonHints();
162                                 }
163                                 else
164                                 {
165                                         // TODO: warning
166                                 }
167                         }
168                         else
169                                 deleteSnapper();
170                 }
171                         break;
172
173                 // set angle (point that defines the angle)
174                 case SetEndAngle:
175                 {
176                         Vector ce(snapPoint(e));
177                         coordinateEvent(&ce);
178                 }
179                         break;
180                 }
181         }
182         else if (e->button() == Qt::RightButton)
183         {
184                 deletePreview();
185                 deleteSnapper();
186                 init(getStatus() - 1);
187         }
188 }
189
190 void ActionDrawArcTangential::coordinateEvent(Vector * e)
191 {
192         if (!e)
193                 return;
194
195         Vector mouse = *e;
196
197         switch (getStatus())
198         {
199         case SetBaseEntity:
200                 break;
201
202         case SetEndAngle:
203                 point = mouse;
204                 trigger();
205                 break;
206
207         default:
208                 break;
209         }
210 }
211
212 void ActionDrawArcTangential::commandEvent(RS_CommandEvent * e)
213 {
214         QString c = e->getCommand().toLower();
215
216         if (checkCommand("help", c))
217         {
218                 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
219                         + getAvailableCommands().join(", "));
220                 return;
221         }
222 }
223
224 QStringList ActionDrawArcTangential::getAvailableCommands()
225 {
226         QStringList cmd;
227         return cmd;
228 }
229
230 void ActionDrawArcTangential::showOptions()
231 {
232         ActionInterface::showOptions();
233
234         if (RS_DIALOGFACTORY != NULL)
235                 RS_DIALOGFACTORY->requestOptions(this, true);
236         updateMouseButtonHints();
237 }
238
239 void ActionDrawArcTangential::hideOptions()
240 {
241         ActionInterface::hideOptions();
242
243         if (RS_DIALOGFACTORY != NULL)
244                 RS_DIALOGFACTORY->requestOptions(this, false);
245 }
246
247 void ActionDrawArcTangential::updateMouseButtonHints()
248 {
249         switch (getStatus())
250         {
251         case SetBaseEntity:
252                 RS_DIALOGFACTORY->updateMouseWidget(
253                         tr("Specify base entity"),
254                         tr("Cancel"));
255                 break;
256
257         case SetEndAngle:
258                 RS_DIALOGFACTORY->updateMouseWidget(
259                         tr("Specify end angle"), tr("Back"));
260                 break;
261
262         default:
263                 RS_DIALOGFACTORY->updateMouseWidget("", "");
264                 break;
265         }
266 }
267
268 void ActionDrawArcTangential::updateMouseCursor()
269 {
270         graphicView->setMouseCursor(RS2::CadCursor);
271 }
272
273 void ActionDrawArcTangential::updateToolBar()
274 {
275         if (!isFinished())
276                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
277         else
278                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
279 }
280
281 void ActionDrawArcTangential::setRadius(double r)
282 {
283         data.radius = r;
284 }
285
286 double ActionDrawArcTangential::getRadius()
287 {
288         return data.radius;
289 }