]> Shamusworld >> Repos - architektonas/blob - src/actions/rs_actiondrawarctangential.cpp
Refactoring: Moved RS_GraphicView to GraphicView.
[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_commandevent.h"
18 #include "rs_dialogfactory.h"
19 #include "graphicview.h"
20 #include "rs_preview.h"
21
22 RS_ActionDrawArcTangential::RS_ActionDrawArcTangential(RS_EntityContainer & container, GraphicView & graphicView): RS_PreviewActionInterface("Draw arcs tangential",
23                 container, graphicView)
24 {
25         reset();
26 }
27
28 RS_ActionDrawArcTangential::~RS_ActionDrawArcTangential()
29 {
30 }
31
32 /*virtual*/ RS2::ActionType RS_ActionDrawArcTangential::rtti()
33 {
34         return RS2::ActionDrawArcTangential;
35 }
36
37 void RS_ActionDrawArcTangential::reset()
38 {
39         baseEntity = NULL;
40         isStartPoint = false;
41         point = Vector(false);
42 }
43
44 void RS_ActionDrawArcTangential::init(int status)
45 {
46         RS_PreviewActionInterface::init(status);
47         //reset();
48 }
49
50 void RS_ActionDrawArcTangential::trigger()
51 {
52         RS_PreviewActionInterface::trigger();
53
54         if (point.valid == false || baseEntity == NULL)
55         {
56                 RS_DEBUG->print("RS_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 RS_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 RS_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 RS_ActionDrawArcTangential::mouseReleaseEvent(QMouseEvent * e)
138 {
139         if (e->button() == Qt::LeftButton)
140         {
141                 switch (getStatus())
142                 {
143                 // set base entity:
144                 case SetBaseEntity: {
145                         Vector coord = graphicView->toGraph(e->x(), e->y());
146                         RS_Entity * entity = catchEntity(coord, RS2::ResolveAll);
147
148                         if (entity != NULL)
149                         {
150                                 if (entity->isAtomic())
151                                 {
152                                         baseEntity = (RS_AtomicEntity *)entity;
153
154                                         if (baseEntity->getStartpoint().distanceTo(coord)
155                                             < baseEntity->getEndpoint().distanceTo(coord))
156                                                 isStartPoint = true;
157                                         else
158                                                 isStartPoint = false;
159                                         setStatus(SetEndAngle);
160                                         updateMouseButtonHints();
161                                 }
162                                 else
163                                 {
164                                         // TODO: warning
165                                 }
166                         }
167                         else
168                                 deleteSnapper();
169                 }
170                 break;
171
172                 // set angle (point that defines the angle)
173                 case SetEndAngle: {
174                         Vector ce(snapPoint(e));
175                         coordinateEvent(&ce);
176                 }
177                 break;
178                 }
179         }
180         else if (e->button() == Qt::RightButton)
181         {
182                 deletePreview();
183                 deleteSnapper();
184                 init(getStatus() - 1);
185         }
186 }
187
188 void RS_ActionDrawArcTangential::coordinateEvent(Vector * e)
189 {
190         if (e == NULL)
191                 return;
192
193         Vector mouse = *e;
194
195         switch (getStatus())
196         {
197         case SetBaseEntity:
198                 break;
199
200         case SetEndAngle:
201                 point = mouse;
202                 trigger();
203                 break;
204
205         default:
206                 break;
207         }
208 }
209
210 void RS_ActionDrawArcTangential::commandEvent(RS_CommandEvent * e)
211 {
212         QString c = e->getCommand().toLower();
213
214         if (checkCommand("help", c))
215         {
216                 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
217                         + getAvailableCommands().join(", "));
218                 return;
219         }
220 }
221
222 QStringList RS_ActionDrawArcTangential::getAvailableCommands()
223 {
224         QStringList cmd;
225         return cmd;
226 }
227
228 void RS_ActionDrawArcTangential::showOptions()
229 {
230         RS_ActionInterface::showOptions();
231
232         if (RS_DIALOGFACTORY != NULL)
233                 RS_DIALOGFACTORY->requestOptions(this, true);
234         updateMouseButtonHints();
235 }
236
237 void RS_ActionDrawArcTangential::hideOptions()
238 {
239         RS_ActionInterface::hideOptions();
240
241         if (RS_DIALOGFACTORY != NULL)
242                 RS_DIALOGFACTORY->requestOptions(this, false);
243 }
244
245 void RS_ActionDrawArcTangential::updateMouseButtonHints()
246 {
247         switch (getStatus())
248         {
249         case SetBaseEntity:
250                 RS_DIALOGFACTORY->updateMouseWidget(
251                         tr("Specify base entity"),
252                         tr("Cancel"));
253                 break;
254
255         case SetEndAngle:
256                 RS_DIALOGFACTORY->updateMouseWidget(
257                         tr("Specify end angle"), tr("Back"));
258                 break;
259
260         default:
261                 RS_DIALOGFACTORY->updateMouseWidget("", "");
262                 break;
263         }
264 }
265
266 void RS_ActionDrawArcTangential::updateMouseCursor()
267 {
268         graphicView->setMouseCursor(RS2::CadCursor);
269 }
270
271 void RS_ActionDrawArcTangential::updateToolBar()
272 {
273         if (!isFinished())
274                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
275         else
276                 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
277 }
278
279 void RS_ActionDrawArcTangential::setRadius(double r)
280 {
281         data.radius = r;
282 }
283
284 double RS_ActionDrawArcTangential::getRadius()
285 {
286         return data.radius;
287 }
288