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