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