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_actiondrawcircle2p.h"
30
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_circle.h"
35 #include "rs_coordinateevent.h"
36 #include "rs_preview.h"
37
38 struct RS_ActionDrawCircle2P::Points {
39 /**
40 * 1st point.
41 */
42 RS_Vector point1;
43 /**
44 * 2nd point.
45 */
46 RS_Vector point2;
47 };
48
RS_ActionDrawCircle2P(RS_EntityContainer & container,RS_GraphicView & graphicView)49 RS_ActionDrawCircle2P::RS_ActionDrawCircle2P(RS_EntityContainer& container,
50 RS_GraphicView& graphicView)
51 :RS_PreviewActionInterface("Draw circles",
52 container, graphicView)
53 , data(new RS_CircleData())
54 , pPoints(new Points{})
55 {
56 actionType=RS2::ActionDrawCircle2P;
57 reset();
58 }
59
60 RS_ActionDrawCircle2P::~RS_ActionDrawCircle2P() = default;
61
reset()62 void RS_ActionDrawCircle2P::reset() {
63 data.reset(new RS_CircleData{});
64 pPoints->point1 = {};
65 pPoints->point2 = {};
66 }
67
68
69
init(int status)70 void RS_ActionDrawCircle2P::init(int status) {
71 RS_PreviewActionInterface::init(status);
72
73 reset();
74 }
75
76
77
trigger()78 void RS_ActionDrawCircle2P::trigger() {
79 RS_PreviewActionInterface::trigger();
80
81 preparePreview();
82 if (data->isValid()) {
83 RS_Circle* circle = new RS_Circle(container,
84 *data);
85 circle->setLayerToActive();
86 circle->setPenToActive();
87 container->addEntity(circle);
88
89 // upd. undo list:
90 if (document) {
91 document->startUndoCycle();
92 document->addUndoable(circle);
93 document->endUndoCycle();
94 }
95
96 RS_Vector rz = graphicView->getRelativeZero();
97 graphicView->redraw(RS2::RedrawDrawing);
98 graphicView->moveRelativeZero(rz);
99
100 setStatus(SetPoint1);
101 reset();
102 } else
103 RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid Circle data."));
104 }
105
106
107
preparePreview()108 void RS_ActionDrawCircle2P::preparePreview() {
109 data.reset(new RS_CircleData{});
110 if (pPoints->point1.valid && pPoints->point2.valid) {
111 RS_Circle circle(nullptr, *data);
112 bool suc = circle.createFrom2P(pPoints->point1, pPoints->point2);
113 if (suc) {
114 data.reset(new RS_CircleData(circle.getData()));
115 }
116 }
117 }
118
119
mouseMoveEvent(QMouseEvent * e)120 void RS_ActionDrawCircle2P::mouseMoveEvent(QMouseEvent* e) {
121 RS_Vector mouse = snapPoint(e);
122 switch (getStatus()) {
123 case SetPoint1:
124 pPoints->point1 = mouse;
125 break;
126
127 case SetPoint2:
128 pPoints->point2 = mouse;
129 preparePreview();
130 if (data->isValid()) {
131 RS_Circle* circle = new RS_Circle(preview.get(), *data);
132 deletePreview();
133 preview->addEntity(circle);
134 drawPreview();
135 }
136 break;
137
138 default:
139 break;
140 }
141 }
142
143
144
mouseReleaseEvent(QMouseEvent * e)145 void RS_ActionDrawCircle2P::mouseReleaseEvent(QMouseEvent* e) {
146 if (e->button()==Qt::LeftButton) {
147 RS_CoordinateEvent ce(snapPoint(e));
148 coordinateEvent(&ce);
149 } else if (e->button()==Qt::RightButton) {
150 deletePreview();
151 init(getStatus()-1);
152 }
153 }
154
155
156
coordinateEvent(RS_CoordinateEvent * e)157 void RS_ActionDrawCircle2P::coordinateEvent(RS_CoordinateEvent* e) {
158 if (e==NULL) {
159 return;
160 }
161
162 RS_Vector mouse = e->getCoordinate();
163
164 switch (getStatus()) {
165 case SetPoint1:
166 pPoints->point1 = mouse;
167 graphicView->moveRelativeZero(mouse);
168 setStatus(SetPoint2);
169 break;
170
171 case SetPoint2:
172 pPoints->point2 = mouse;
173 graphicView->moveRelativeZero(mouse);
174 trigger();
175 break;
176
177 default:
178 break;
179 }
180 }
181
182
183
commandEvent(RS_CommandEvent * e)184 void RS_ActionDrawCircle2P::commandEvent(RS_CommandEvent* e) {
185 QString c = e->getCommand().toLower();
186
187 if (checkCommand("help", c)) {
188 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
189 + getAvailableCommands().join(", "));
190 return;
191 }
192
193 }
194
195
196
getAvailableCommands()197 QStringList RS_ActionDrawCircle2P::getAvailableCommands() {
198 QStringList cmd;
199 return cmd;
200 }
201
202
203
updateMouseButtonHints()204 void RS_ActionDrawCircle2P::updateMouseButtonHints() {
205 switch (getStatus()) {
206 case SetPoint1:
207 RS_DIALOGFACTORY->updateMouseWidget(
208 tr("Specify first point"), tr("Cancel"));
209 break;
210 case SetPoint2:
211 RS_DIALOGFACTORY->updateMouseWidget(
212 tr("Specify second point"), tr("Back"));
213 break;
214 default:
215 RS_DIALOGFACTORY->updateMouseWidget();
216 break;
217 }
218 }
219
220
221
updateMouseCursor()222 void RS_ActionDrawCircle2P::updateMouseCursor() {
223 graphicView->setMouseCursor(RS2::CadCursor);
224 }
225
226 // EOF
227
228