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"
18 #include "rs_dialogfactory.h"
19 #include "rs_graphicview.h"
20 #include "rs_preview.h"
22 RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer & container, RS_GraphicView & graphicView):
23 RS_PreviewActionInterface("Draw arcs", container, graphicView)
28 RS_ActionDrawArc::~RS_ActionDrawArc()
32 RS2::ActionType RS_ActionDrawArc::rtti()
34 return RS2::ActionDrawArc;
37 void RS_ActionDrawArc::reset()
39 //bool rev = data.reversed;
42 data = RS_ArcData(Vector(false), 0.0, 2 * M_PI, 0.0, true);
44 data = RS_ArcData(Vector(false), 0.0, 0.0, 2 * M_PI, false);
47 void RS_ActionDrawArc::init(int status)
49 RS_PreviewActionInterface::init(status);
53 void RS_ActionDrawArc::trigger()
55 RS_PreviewActionInterface::trigger();
57 RS_Arc * arc = new RS_Arc(container, data);
58 arc->setLayerToActive();
59 arc->setPenToActive();
60 container->addEntity(arc);
65 document->startUndoCycle();
66 document->addUndoable(arc);
67 document->endUndoCycle();
71 graphicView->moveRelativeZero(Vector(0.0, 0.0));
72 graphicView->drawEntity(arc);
73 graphicView->moveRelativeZero(arc->getCenter());
79 RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d", arc->getId());
82 void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent * e)
84 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
85 Vector mouse = snapPoint(e);
95 if (data.center.valid)
97 data.radius = data.center.distanceTo(mouse);
100 preview->addEntity(new RS_Circle(preview, RS_CircleData(data.center, data.radius)));
106 data.angle1 = data.center.angleTo(mouse);
109 data.angle2 = RS_Math::correctAngle(data.angle1 - M_PI / 3);
111 data.angle2 = RS_Math::correctAngle(data.angle1 + M_PI / 3);
115 preview->addEntity(new RS_Arc(preview, data));
120 data.angle2 = data.center.angleTo(mouse);
123 preview->addEntity(new RS_Arc(preview, data));
128 data.angle2 = data.angle1 + data.center.angleTo(mouse);
131 preview->addEntity(new RS_Arc(preview, data));
137 double x = data.center.distanceTo(mouse);
139 if (fabs(x / (2 * data.radius)) <= 1.0)
141 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
144 preview->addEntity(new RS_Arc(preview, data));
154 RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
157 void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent * e)
159 if (e->button() == Qt::LeftButton)
161 Vector ce(snapPoint(e));
162 coordinateEvent(&ce);
164 else if (e->button() == Qt::RightButton)
168 init(getStatus() - 1);
172 void RS_ActionDrawArc::coordinateEvent(Vector * e)
183 graphicView->moveRelativeZero(mouse);
185 setStatus(SetRadius);
190 if (data.center.valid)
191 data.radius = data.center.distanceTo(mouse);
193 setStatus(SetAngle1);
197 data.angle1 = data.center.angleTo(mouse);
198 setStatus(SetAngle2);
202 data.angle2 = data.center.angleTo(mouse);
207 data.angle2 = data.angle1 + data.center.angleTo(mouse);
213 double x = data.center.distanceTo(mouse);
215 if (fabs(x / (2 * data.radius)) <= 1.0)
217 data.angle2 = data.angle1 + asin(x / (2 * data.radius)) * 2;
228 void RS_ActionDrawArc::commandEvent(RS_CommandEvent * e)
230 QString c = e->getCommand().toLower();
232 if (RS_COMMANDS->checkCommand("help", c))
234 if (RS_DIALOGFACTORY != NULL)
235 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
236 + getAvailableCommands().join(", "));
240 if (RS_COMMANDS->checkCommand("reversed", c))
243 setReversed(!isReversed());
245 if (RS_DIALOGFACTORY != NULL)
246 RS_DIALOGFACTORY->requestOptions(this, true, true);
254 double r = RS_Math::eval(c, &ok);
259 setStatus(SetAngle1);
261 else if (RS_DIALOGFACTORY != NULL)
262 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
269 double a = RS_Math::eval(c, &ok);
273 data.angle1 = RS_Math::deg2rad(a);
274 setStatus(SetAngle2);
276 else if (RS_DIALOGFACTORY != NULL)
277 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
284 if (RS_COMMANDS->checkCommand("angle", c))
285 setStatus(SetIncAngle);
286 else if (RS_COMMANDS->checkCommand("chord length", c))
287 setStatus(SetChordLength);
291 double a = RS_Math::eval(c, &ok);
295 data.angle2 = RS_Math::deg2rad(a);
298 else if (RS_DIALOGFACTORY != NULL)
299 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
306 double a = RS_Math::eval(c, &ok);
310 data.angle2 = data.angle1 + RS_Math::deg2rad(a);
313 else if (RS_DIALOGFACTORY != NULL)
314 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
319 case SetChordLength: {
321 double l = RS_Math::eval(c, &ok);
325 if (fabs(l / (2 * data.radius)) <= 1.0)
327 data.angle2 = data.angle1 + asin(l / (2 * data.radius)) * 2;
330 else if (RS_DIALOGFACTORY != NULL)
331 RS_DIALOGFACTORY->commandMessage(
332 tr("Not a valid chord length"));
335 else if (RS_DIALOGFACTORY != NULL)
336 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
346 QStringList RS_ActionDrawArc::getAvailableCommands()
349 cmd += RS_COMMANDS->command("reversed");
353 void RS_ActionDrawArc::updateMouseButtonHints()
355 if (RS_DIALOGFACTORY != NULL)
360 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
364 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
368 RS_DIALOGFACTORY->updateMouseWidget(
369 tr("Specify start angle:"), tr("Back"));
373 RS_DIALOGFACTORY->updateMouseWidget(
374 tr("Specify end angle or [Angle/chord Length]"),
379 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
384 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
389 RS_DIALOGFACTORY->updateMouseWidget("", "");
395 void RS_ActionDrawArc::showOptions()
397 RS_ActionInterface::showOptions();
399 if (RS_DIALOGFACTORY != NULL)
400 RS_DIALOGFACTORY->requestOptions(this, true);
403 void RS_ActionDrawArc::hideOptions()
405 RS_ActionInterface::hideOptions();
407 if (RS_DIALOGFACTORY != NULL)
408 RS_DIALOGFACTORY->requestOptions(this, false);
411 void RS_ActionDrawArc::updateMouseCursor()
413 graphicView->setMouseCursor(RS2::CadCursor);
416 void RS_ActionDrawArc::updateToolBar()
418 if (RS_DIALOGFACTORY == NULL)
422 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarSnap);
424 RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarArcs);
427 bool RS_ActionDrawArc::isReversed()
429 return data.reversed;
432 void RS_ActionDrawArc::setReversed(bool r)