1 // rs_actiondrawarc.cpp
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
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 06/03/2010 Added this text. :-)
15 #include "rs_actiondrawarc.h"
17 #include "rs_commandevent.h"
19 #include "rs_dialogfactory.h"
20 #include "graphicview.h"
21 #include "rs_preview.h"
23 RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer & container, GraphicView & graphicView):
24 RS_PreviewActionInterface("Draw arcs", container, graphicView)
29 RS_ActionDrawArc::~RS_ActionDrawArc()
33 RS2::ActionType RS_ActionDrawArc::rtti()
35 return RS2::ActionDrawArc;
38 void RS_ActionDrawArc::reset()
40 //bool rev = data.reversed;
43 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
45 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
48 void RS_ActionDrawArc::init(int status)
50 RS_PreviewActionInterface::init(status);
54 void RS_ActionDrawArc::trigger()
56 RS_PreviewActionInterface::trigger();
58 RS_Arc * arc = new RS_Arc(container, data);
59 arc->setLayerToActive();
60 arc->setPenToActive();
61 container->addEntity(arc);
66 document->startUndoCycle();
67 document->addUndoable(arc);
68 document->endUndoCycle();
72 graphicView->moveRelativeZero(Vector(0.0, 0.0));
73 graphicView->drawEntity(arc);
74 graphicView->moveRelativeZero(arc->getCenter());
80 RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d", arc->getId());
83 void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
85 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
86 Vector mouse = snapPoint(e);
96 if (data.center.valid)
98 data.radius = data.center.distanceTo(mouse);
101 preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
107 data.angle1 = data.center.angleTo(mouse);
110 data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
112 data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
116 preview->addEntity(new RS_Arc(preview, data));
121 data.angle2 = data.center.angleTo(mouse);
124 preview->addEntity(new RS_Arc(preview, data));
129 data.angle2 = data.angle1 + data.center.angleTo(mouse);
132 preview->addEntity(new RS_Arc(preview, data));
138 double x = data.center.distanceTo(mouse);
140 if (fabs(x / (2 * data.radius)) <= 1.0)
142 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
145 preview->addEntity(new RS_Arc(preview, data));
155 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
158 void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
160 if (e->button() == Qt::LeftButton)
162 Vector ce(snapPoint(e));
163 coordinateEvent(&ce);
165 else if (e->button() == Qt::RightButton)
169 init(getStatus() - 1);
173 void RS_ActionDrawArc::coordinateEvent(Vector * e)
184 graphicView->moveRelativeZero(mouse);
186 setStatus(SetRadius);
191 if (data.center.valid)
192 data.radius = data.center.distanceTo(mouse);
194 setStatus(SetAngle1);
198 data.angle1 = data.center.angleTo(mouse);
199 setStatus(SetAngle2);
203 data.angle2 = data.center.angleTo(mouse);
208 data.angle2 = data.angle1 + data.center.angleTo(mouse);
214 double x = data.center.distanceTo(mouse);
216 if (fabs(x / (2 * data.radius)) <= 1.0)
218 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
229 void RS_ActionDrawArc::commandEvent(RS_CommandEvent * e)
231 QString c = e->getCommand().toLower();
233 if (RS_COMMANDS->checkCommand("help", c))
235 if (RS_DIALOGFACTORY != NULL)
236 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
237 + getAvailableCommands().join(", "));
241 if (RS_COMMANDS->checkCommand("reversed", c))
244 setReversed(!isReversed());
246 if (RS_DIALOGFACTORY != NULL)
247 RS_DIALOGFACTORY->requestOptions(this, true, true);
255 double r = RS_Math::eval(c, &ok);
260 setStatus(SetAngle1);
262 else if (RS_DIALOGFACTORY != NULL)
263 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
270 double a = RS_Math::eval(c, &ok);
274 data.angle1 = RS_Math::deg2rad(a);
275 setStatus(SetAngle2);
277 else if (RS_DIALOGFACTORY != NULL)
278 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
285 if (RS_COMMANDS->checkCommand("angle", c))
286 setStatus(SetIncAngle);
287 else if (RS_COMMANDS->checkCommand("chord length", c))
288 setStatus(SetChordLength);
292 double a = RS_Math::eval(c, &ok);
296 data.angle2 = RS_Math::deg2rad(a);
299 else if (RS_DIALOGFACTORY != NULL)
300 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
307 double a = RS_Math::eval(c, &ok);
311 data.angle2 = data.angle1 + RS_Math::deg2rad(a);
314 else if (RS_DIALOGFACTORY != NULL)
315 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
320 case SetChordLength: {
322 double l = RS_Math::eval(c, &ok);
326 if (fabs(l / (2 * data.radius)) <= 1.0)
328 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
331 else if (RS_DIALOGFACTORY != NULL)
332 RS_DIALOGFACTORY->commandMessage(
333 tr("Not a valid chord length"));
336 else if (RS_DIALOGFACTORY != NULL)
337 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
347 QStringList RS_ActionDrawArc::getAvailableCommands()
350 cmd += RS_COMMANDS->command("reversed");
354 void RS_ActionDrawArc::updateMouseButtonHints()
356 if (RS_DIALOGFACTORY != NULL)
361 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
365 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
369 RS_DIALOGFACTORY->updateMouseWidget(
370 tr("Specify start angle:"), tr("Back"));
374 RS_DIALOGFACTORY->updateMouseWidget(
375 tr("Specify end angle or [Angle/chord Length]"),
380 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
385 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
390 RS_DIALOGFACTORY->updateMouseWidget("", "");
396 void RS_ActionDrawArc::showOptions()
398 RS_ActionInterface::showOptions();
400 if (RS_DIALOGFACTORY != NULL)
401 RS_DIALOGFACTORY->requestOptions(this, true);
404 void RS_ActionDrawArc::hideOptions()
406 RS_ActionInterface::hideOptions();
408 if (RS_DIALOGFACTORY != NULL)
409 RS_DIALOGFACTORY->requestOptions(this, false);
412 void RS_ActionDrawArc::updateMouseCursor()
414 graphicView->setMouseCursor(RS2::CadCursor);
417 void RS_ActionDrawArc::updateToolBar()
419 if (RS_DIALOGFACTORY == NULL)
423 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
425 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
428 bool RS_ActionDrawArc::isReversed()
430 return data.reversed;
433 void RS_ActionDrawArc::setReversed(bool r)