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_actiondrawlinebisector.h"
30
31 #include "rs_dialogfactory.h"
32 #include "rs_graphicview.h"
33 #include "rs_commandevent.h"
34 #include "rs_creation.h"
35 #include "rs_line.h"
36 #include "rs_math.h"
37 #include "rs_preview.h"
38 #include "rs_debug.h"
39
40 struct RS_ActionDrawLineBisector::Points {
41 /** Mouse pos when choosing the 1st line */
42 RS_Vector coord1;
43 /** Mouse pos when choosing the 2nd line */
44 RS_Vector coord2;
45 };
46
RS_ActionDrawLineBisector(RS_EntityContainer & container,RS_GraphicView & graphicView)47 RS_ActionDrawLineBisector::RS_ActionDrawLineBisector(
48 RS_EntityContainer& container,
49 RS_GraphicView& graphicView)
50 :RS_PreviewActionInterface("Draw Bisectors", container, graphicView)
51 ,bisector(nullptr)
52 ,line1(nullptr)
53 ,line2(nullptr)
54 ,length(10.)
55 ,number(1)
56 , pPoints(new Points{})
57 ,lastStatus(SetLine1)
58 {
59 actionType=RS2::ActionDrawLineBisector;
60 }
61
62 RS_ActionDrawLineBisector::~RS_ActionDrawLineBisector() = default;
63
64
setLength(double l)65 void RS_ActionDrawLineBisector::setLength(double l) {
66 length = l;
67 }
68
getLength() const69 double RS_ActionDrawLineBisector::getLength() const{
70 return length;
71 }
72
setNumber(int n)73 void RS_ActionDrawLineBisector::setNumber(int n) {
74 number = n;
75 }
76
getNumber() const77 int RS_ActionDrawLineBisector::getNumber() const {
78 return number;
79 }
80
81
init(int status)82 void RS_ActionDrawLineBisector::init(int status) {
83 RS_PreviewActionInterface::init(status);
84 if(status>=0) {
85 RS_Snapper::suspend();
86 }
87
88 if (status<SetLine2) {
89 if(line2 && line2->isHighlighted()){
90 line2->setHighlighted(false);
91 }
92 if(status<0 && line1 && line1->isHighlighted()){
93 line1->setHighlighted(false);
94 }
95 graphicView->redraw(RS2::RedrawDrawing);
96 }
97 }
98
trigger()99 void RS_ActionDrawLineBisector::trigger() {
100 RS_PreviewActionInterface::trigger();
101
102 for(auto p: {line1, line2}){
103 if(p && p->isHighlighted()){
104 p->setHighlighted(false);
105 }
106 }
107 graphicView->redraw(RS2::RedrawDrawing);
108
109 RS_Creation creation(container, graphicView);
110 creation.createBisector(pPoints->coord1,
111 pPoints->coord2,
112 length,
113 number,
114 line1,
115 line2);
116 }
117
118
119
mouseMoveEvent(QMouseEvent * e)120 void RS_ActionDrawLineBisector::mouseMoveEvent(QMouseEvent* e) {
121 RS_DEBUG->print("RS_ActionDrawLineBisector::mouseMoveEvent begin");
122
123 RS_Vector mouse = RS_Vector(graphicView->toGraphX(e->x()),
124 graphicView->toGraphY(e->y()));
125
126 switch (getStatus()) {
127 case SetLine1:
128 break;
129
130 case SetLine2: {
131 pPoints->coord2 = mouse;
132 RS_Entity* en = catchEntity(e, RS2::ResolveAll);
133 if(en==line1) break;
134 if (en && en->rtti()==RS2::EntityLine) {
135 if(line2 && line2->isHighlighted()){
136 line2->setHighlighted(false);
137 }
138 line2 = static_cast<RS_Line*>(en);
139 line2->setHighlighted(true);
140 graphicView->redraw(RS2::RedrawDrawing);
141
142 deletePreview();
143
144 RS_Creation creation(preview.get(), nullptr, false);
145 creation.createBisector(pPoints->coord1,
146 pPoints->coord2,
147 length,
148 number,
149 line1,
150 line2);
151 drawPreview();
152 }else{
153 if(line2 && line2->isHighlighted()){
154 line2->setHighlighted(false);
155 graphicView->redraw(RS2::RedrawDrawing);
156 }
157 line2=nullptr;
158
159 }
160 }
161 break;
162
163 default:
164 break;
165 }
166
167 RS_DEBUG->print("RS_ActionDrawLineBisector::mouseMoveEvent end");
168 }
169
170
171
mouseReleaseEvent(QMouseEvent * e)172 void RS_ActionDrawLineBisector::mouseReleaseEvent(QMouseEvent* e) {
173
174 if (e->button()==Qt::RightButton) {
175 deletePreview();
176 init(getStatus()-1);
177 } else {
178
179 RS_Vector mouse = RS_Vector(graphicView->toGraphX(e->x()),
180 graphicView->toGraphY(e->y()));
181
182 switch (getStatus()) {
183 case SetLine1: {
184 pPoints->coord1 = mouse;
185 RS_Entity* en = catchEntity(e, RS2::ResolveAll);
186 if (en && en->rtti()==RS2::EntityLine) {
187 line1 = static_cast<RS_Line*>(en);
188 line1->setHighlighted(true);
189 graphicView->redraw(RS2::RedrawDrawing);
190 line2=nullptr;
191 setStatus(SetLine2);
192 }
193 }
194 break;
195
196 case SetLine2:
197 pPoints->coord2 = mouse;
198 trigger();
199 setStatus(SetLine1);
200 break;
201 }
202 }
203
204 }
205
206
commandEvent(RS_CommandEvent * e)207 void RS_ActionDrawLineBisector::commandEvent(RS_CommandEvent* e) {
208 QString c = e->getCommand().toLower();
209
210 if (checkCommand("help", c)) {
211 RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
212 + getAvailableCommands().join(", "));
213 return;
214 }
215
216 switch (getStatus()) {
217 case SetLine1:
218 case SetLine2:
219 lastStatus = (Status)getStatus();
220 if (checkCommand("length", c)) {
221 deletePreview();
222 setStatus(SetLength);
223 } else if (checkCommand("number", c)) {
224 deletePreview();
225 setStatus(SetNumber);
226 }
227 break;
228
229 case SetLength: {
230 bool ok;
231 double l = RS_Math::eval(c, &ok);
232 if (ok) {
233 e->accept();
234 length = l;
235 } else {
236 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
237 }
238 RS_DIALOGFACTORY->requestOptions(this, true, true);
239 setStatus(lastStatus);
240 }
241 break;
242
243 case SetNumber: {
244 bool ok;
245 int n = (int)RS_Math::eval(c, &ok);
246 if (ok) {
247 e->accept();
248 if(n>0 && n<=200)
249 number = n;
250 else
251 RS_DIALOGFACTORY->commandMessage(tr("Number sector lines not in range: ", "number of bisector to create must be in [1, 200]")+QString::number(n));
252 } else {
253 RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
254 }
255 RS_DIALOGFACTORY->requestOptions(this, true, true);
256 setStatus(lastStatus);
257 }
258 break;
259
260
261 default:
262 break;
263 }
264 }
265
266
267
getAvailableCommands()268 QStringList RS_ActionDrawLineBisector::getAvailableCommands() {
269 QStringList cmd;
270
271 switch (getStatus()) {
272 case SetLine1:
273 case SetLine2:
274 cmd += command("length");
275 cmd += command("number");
276 break;
277 default:
278 break;
279 }
280
281 return cmd;
282 }
283
284
updateMouseButtonHints()285 void RS_ActionDrawLineBisector::updateMouseButtonHints() {
286 switch (getStatus()) {
287 case SetLine1:
288 RS_DIALOGFACTORY->updateMouseWidget(tr("Select first line"),
289 tr("Cancel"));
290 break;
291 case SetLine2:
292 RS_DIALOGFACTORY->updateMouseWidget(tr("Select second line"),
293 tr("Back"));
294 break;
295 case SetLength:
296 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter bisector length:"),
297 tr("Back"));
298 break;
299 case SetNumber:
300 RS_DIALOGFACTORY->updateMouseWidget(tr("Enter number of bisectors:"),
301 tr("Back"));
302 break;
303 default:
304 RS_DIALOGFACTORY->updateMouseWidget();
305 break;
306 }
307 }
308
309
310
showOptions()311 void RS_ActionDrawLineBisector::showOptions() {
312 RS_ActionInterface::showOptions();
313
314 RS_DIALOGFACTORY->requestOptions(this, true);
315 }
316
317
318
hideOptions()319 void RS_ActionDrawLineBisector::hideOptions() {
320 RS_ActionInterface::hideOptions();
321
322 RS_DIALOGFACTORY->requestOptions(this, false);
323 }
324
325
326
updateMouseCursor()327 void RS_ActionDrawLineBisector::updateMouseCursor() {
328 graphicView->setMouseCursor(RS2::SelectCursor);
329 }
330
331 // EOF
332