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