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_actiondrawcirclecr.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_math.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39
40 /**
41 * Constructor.
42 */
RS_ActionDrawCircleCR(RS_EntityContainer & container,RS_GraphicView & graphicView)43 RS_ActionDrawCircleCR::RS_ActionDrawCircleCR(RS_EntityContainer& container,
44 RS_GraphicView& graphicView)
45 :RS_PreviewActionInterface("Draw circles CR",
46 container, graphicView)
47 ,data(new RS_CircleData())
48 {
49 actionType=RS2::ActionDrawCircleCR;
50
51 reset();
52 }
53
54
55
56 RS_ActionDrawCircleCR::~RS_ActionDrawCircleCR() = default;
57
58
reset()59 void RS_ActionDrawCircleCR::reset() {
60 data.reset(new RS_CircleData{RS_Vector{false}, 0.0});
61 }
62
63
64
init(int status)65 void RS_ActionDrawCircleCR::init(int status) {
66 RS_PreviewActionInterface::init(status);
67 }
68
69
70
trigger()71 void RS_ActionDrawCircleCR::trigger() {
72 RS_PreviewActionInterface::trigger();
73
74 RS_Circle* circle = new RS_Circle(container,
75 *data);
76 circle->setLayerToActive();
77 circle->setPenToActive();
78
79 switch(getStatus()) {
80 case SetCenter:
81 container->addEntity(circle);
82 graphicView->moveRelativeZero(circle->getCenter());
83 break;
84 case SetRadius:
85 break;
86 }
87
88 // upd. undo list:
89 if (document) {
90 document->startUndoCycle();
91 document->addUndoable(circle);
92 document->endUndoCycle();
93 }
94 graphicView->redraw(RS2::RedrawDrawing);
95
96 setStatus(SetCenter);
97
98 RS_DEBUG->print("RS_ActionDrawCircleCR::trigger(): circle added: %d",
99 circle->getId());
100 }
101
setRadius(double r)102 void RS_ActionDrawCircleCR::setRadius(double r)
103 {
104 if(r>RS_TOLERANCE){
105 data->radius=r;
106 }else{
107 RS_DIALOGFACTORY->commandMessage(tr("radius=%1 is invalid").arg(r));
108 }
109 }
110
111
mouseMoveEvent(QMouseEvent * e)112 void RS_ActionDrawCircleCR::mouseMoveEvent(QMouseEvent* e) {
113 RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent begin");
114
115 RS_Vector mouse = snapPoint(e);
116 switch (getStatus()) {
117 case SetCenter:
118 data->center = mouse;
119 deletePreview();
120 preview->addEntity(new RS_Circle(preview.get(),
121 *data));
122 drawPreview();
123 break;
124 }
125
126 RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent end");
127 }
128
129
130
mouseReleaseEvent(QMouseEvent * e)131 void RS_ActionDrawCircleCR::mouseReleaseEvent(QMouseEvent* e) {
132 if (e->button()==Qt::LeftButton) {
133 RS_CoordinateEvent ce(snapPoint(e));
134 coordinateEvent(&ce);
135 } else if (e->button()==Qt::RightButton) {
136 deletePreview();
137 init(getStatus()-1);
138 }
139 }
140
141
142
coordinateEvent(RS_CoordinateEvent * e)143 void RS_ActionDrawCircleCR::coordinateEvent(RS_CoordinateEvent* e) {
144 if (e==NULL) {
145 return;
146 }
147
148 RS_Vector mouse = e->getCoordinate();
149
150 switch (getStatus()) {
151 case SetCenter:
152 data->center = mouse;
153 trigger();
154 break;
155
156 default:
157 break;
158 }
159 }
160
161
162
commandEvent(RS_CommandEvent * e)163 void RS_ActionDrawCircleCR::commandEvent(RS_CommandEvent* e) {
164 QString c = e->getCommand().toLower();
165
166 if (checkCommand("help", c)) {
167 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
168 + getAvailableCommands().join(", "));
169 return;
170 }
171
172 switch (getStatus()) {
173 case SetCenter:
174 if (checkCommand("radius", c)) {
175 deletePreview();
176 setStatus(SetRadius);
177 }
178 break;
179
180 case SetRadius: {
181 bool ok;
182 double r = RS_Math::eval(c, &ok);
183 if (ok) {
184 data->radius = r;
185 e->accept();
186 trigger();
187 } else {
188 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
189 }
190 RS_DIALOGFACTORY->requestOptions(this, true, true);
191 }
192 break;
193
194 default:
195 break;
196 }
197 }
198
199
200
getAvailableCommands()201 QStringList RS_ActionDrawCircleCR::getAvailableCommands() {
202 QStringList cmd;
203
204 switch (getStatus()) {
205 case SetCenter:
206 cmd += command("radius");
207 break;
208 default:
209 break;
210 }
211
212 return cmd;
213 }
214
updateMouseButtonHints()215 void RS_ActionDrawCircleCR::updateMouseButtonHints() {
216 switch (getStatus()) {
217 case SetCenter:
218 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle center"),
219 tr("Cancel"));
220 break;
221 case SetRadius:
222 RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle radius"),
223 tr("Back"));
224 break;
225 default:
226 RS_DIALOGFACTORY->updateMouseWidget();
227 break;
228 }
229 }
230
231
232
showOptions()233 void RS_ActionDrawCircleCR::showOptions() {
234 RS_ActionInterface::showOptions();
235
236 RS_DIALOGFACTORY->requestOptions(this, true);
237 }
238
239
240
hideOptions()241 void RS_ActionDrawCircleCR::hideOptions() {
242 RS_ActionInterface::hideOptions();
243
244 RS_DIALOGFACTORY->requestOptions(this, false);
245 }
246
247
248
updateMouseCursor()249 void RS_ActionDrawCircleCR::updateMouseCursor() {
250 graphicView->setMouseCursor(RS2::CadCursor);
251 }
252
253
getRadius() const254 double RS_ActionDrawCircleCR::getRadius() const{
255 return data->radius;
256 }
257 // EOF
258
259