1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26
27 #include <QAction>
28 #include <QMouseEvent>
29 #include "rs_actiondrawarc3p.h"
30
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_actiondrawarc.h"
34 #include "rs_commands.h"
35 #include "rs_commandevent.h"
36 #include "rs_arc.h"
37 #include "rs_line.h"
38 #include "rs_coordinateevent.h"
39 #include "rs_preview.h"
40
41 struct RS_ActionDrawArc3P::Points {
42 RS_ArcData data;
43 /**
44 * 1st point.
45 */
46 RS_Vector point1;
47 /**
48 * 2nd point.
49 */
50 RS_Vector point2;
51 /**
52 * 3rd point.
53 */
54 RS_Vector point3;
55 };
56
RS_ActionDrawArc3P(RS_EntityContainer & container,RS_GraphicView & graphicView)57 RS_ActionDrawArc3P::RS_ActionDrawArc3P(RS_EntityContainer& container,
58 RS_GraphicView& graphicView)
59 :RS_PreviewActionInterface("Draw arcs 3P",
60 container, graphicView)
61 , pPoints(new Points())
62 {
63 actionType=RS2::ActionDrawArc3P;
64 reset();
65 }
66
67
68
69 RS_ActionDrawArc3P::~RS_ActionDrawArc3P() = default;
70
71
reset()72 void RS_ActionDrawArc3P::reset() {
73 pPoints.reset(new Points{});
74 }
75
76
77
init(int status)78 void RS_ActionDrawArc3P::init(int status) {
79 RS_PreviewActionInterface::init(status);
80
81 //reset();
82 }
83
84
85
trigger()86 void RS_ActionDrawArc3P::trigger() {
87 RS_PreviewActionInterface::trigger();
88
89 preparePreview();
90 if (pPoints->data.isValid()) {
91 RS_Arc* arc = new RS_Arc{container, pPoints->data};
92 arc->setLayerToActive();
93 arc->setPenToActive();
94 container->addEntity(arc);
95
96 // upd. undo list:
97 if (document) {
98 document->startUndoCycle();
99 document->addUndoable(arc);
100 document->endUndoCycle();
101 }
102
103 graphicView->redraw(RS2::RedrawDrawing);
104 graphicView->moveRelativeZero(arc->getEndpoint());
105
106 setStatus(SetPoint1);
107 reset();
108 } else {
109 //RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid arc data."));
110 RS_DIALOGFACTORY->commandMessage(tr("Invalid arc data."));
111 }
112 }
113
114
115
preparePreview()116 void RS_ActionDrawArc3P::preparePreview() {
117 pPoints->data = {};
118 if (pPoints->point1.valid && pPoints->point2.valid && pPoints->point3.valid) {
119 RS_Arc arc(NULL, pPoints->data);
120 bool suc = arc.createFrom3P(pPoints->point1, pPoints->point2, pPoints->point3);
121 if (suc) {
122 pPoints->data = arc.getData();
123 }
124 }
125 }
126
127
mouseMoveEvent(QMouseEvent * e)128 void RS_ActionDrawArc3P::mouseMoveEvent(QMouseEvent* e) {
129 RS_Vector mouse = snapPoint(e);
130
131 switch (getStatus()) {
132 case SetPoint1:
133 pPoints->point1 = mouse;
134 break;
135
136 case SetPoint2:
137 pPoints->point2 = mouse;
138 if (pPoints->point1.valid) {
139 RS_Line* line = new RS_Line{preview.get(), pPoints->point1, pPoints->point2};
140
141 deletePreview();
142 preview->addEntity(line);
143 drawPreview();
144 }
145 break;
146
147 case SetPoint3:
148 pPoints->point3 = mouse;
149 preparePreview();
150 if (pPoints->data.isValid()) {
151 RS_Arc* arc = new RS_Arc(preview.get(), pPoints->data);
152
153 deletePreview();
154 preview->addEntity(arc);
155 drawPreview();
156 }
157 break;
158
159 default:
160 break;
161 }
162 }
163
164
165
mouseReleaseEvent(QMouseEvent * e)166 void RS_ActionDrawArc3P::mouseReleaseEvent(QMouseEvent* e) {
167 if (e->button()==Qt::LeftButton) {
168 RS_CoordinateEvent ce(snapPoint(e));
169 coordinateEvent(&ce);
170 } else if (e->button()==Qt::RightButton) {
171 deletePreview();
172 init(getStatus()-1);
173 }
174 }
175
176
177
coordinateEvent(RS_CoordinateEvent * e)178 void RS_ActionDrawArc3P::coordinateEvent(RS_CoordinateEvent* e) {
179 if (e==NULL) {
180 return;
181 }
182 RS_Vector mouse = e->getCoordinate();
183
184 switch (getStatus()) {
185 case SetPoint1:
186 pPoints->point1 = mouse;
187 graphicView->moveRelativeZero(mouse);
188 setStatus(SetPoint2);
189 break;
190
191 case SetPoint2:
192 pPoints->point2 = mouse;
193 graphicView->moveRelativeZero(mouse);
194 setStatus(SetPoint3);
195 break;
196
197 case SetPoint3:
198 pPoints->point3 = mouse;
199 trigger();
200 break;
201
202 default:
203 break;
204 }
205 }
206
207
208
commandEvent(RS_CommandEvent * e)209 void RS_ActionDrawArc3P::commandEvent(RS_CommandEvent* e) {
210 QString c = e->getCommand().toLower();
211
212 if (checkCommand("help", c)) {
213 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
214 + getAvailableCommands().join(", "));
215 return;
216 }
217
218 if (RS_COMMANDS->checkCommand("center", c, rtti())) {
219 finish(false);
220 graphicView->setCurrentAction(
221 new RS_ActionDrawArc(*container, *graphicView));
222 }
223 }
224
225
226
getAvailableCommands()227 QStringList RS_ActionDrawArc3P::getAvailableCommands() {
228 QStringList cmd;
229 return cmd;
230 }
231
232
233
updateMouseButtonHints()234 void RS_ActionDrawArc3P::updateMouseButtonHints() {
235 switch (getStatus()) {
236 case SetPoint1:
237 RS_DIALOGFACTORY->updateMouseWidget(
238 tr("Specify startpoint or [center]"),
239 tr("Cancel"));
240 break;
241 case SetPoint2:
242 RS_DIALOGFACTORY->updateMouseWidget(
243 tr("Specify second point"), tr("Back"));
244 break;
245 case SetPoint3:
246 RS_DIALOGFACTORY->updateMouseWidget(
247 tr("Specify endpoint"), tr("Back"));
248 break;
249 default:
250 RS_DIALOGFACTORY->updateMouseWidget();
251 break;
252 }
253 }
254
255
256
updateMouseCursor()257 void RS_ActionDrawArc3P::updateMouseCursor() {
258 graphicView->setMouseCursor(RS2::CadCursor);
259 }
260
261 // EOF
262
263