~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/actions/rs_actiondrawarc.cpp

  • Committer: Scott Howard
  • Date: 2014-02-21 19:07:55 UTC
  • Revision ID: showard@debian.org-20140221190755-csjax9wb146hgdq4
first commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "rs_actiondrawarc.h"
 
28
 
 
29
#include <QAction>
 
30
#include "rs_dialogfactory.h"
 
31
#include "rs_graphicview.h"
 
32
#include "rs_commands.h"
 
33
#include "rs_commandevent.h"
 
34
 
 
35
 
 
36
RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer& container,
 
37
                                   RS_GraphicView& graphicView)
 
38
        :RS_PreviewActionInterface("Draw arcs",
 
39
                           container, graphicView) {
 
40
 
 
41
    reset();
 
42
}
 
43
 
 
44
 
 
45
 
 
46
RS_ActionDrawArc::~RS_ActionDrawArc() {}
 
47
 
 
48
QAction* RS_ActionDrawArc::createGUIAction(RS2::ActionType /*type*/, QObject* /*parent*/) {
 
49
        // (tr("Arc: Center, Point, Angles")
 
50
    QAction* action = new QAction(tr("&Center, Point, Angles"),NULL);
 
51
        action->setIcon(QIcon(":/extui/arcscraa.png"));
 
52
    //action->zetStatusTip(tr("Draw arcs"));
 
53
    return action;
 
54
}
 
55
 
 
56
 
 
57
void RS_ActionDrawArc::reset() {
 
58
    //bool rev = data.reversed;
 
59
 
 
60
    if (data.reversed) {
 
61
        data = RS_ArcData(RS_Vector(false),
 
62
                          0.0,
 
63
                          2*M_PI, 0.0,
 
64
                          true);
 
65
    } else {
 
66
        data = RS_ArcData(RS_Vector(false),
 
67
                          0.0,
 
68
                          0.0, 2*M_PI,
 
69
                          false);
 
70
    }
 
71
}
 
72
 
 
73
 
 
74
 
 
75
void RS_ActionDrawArc::init(int status) {
 
76
    RS_PreviewActionInterface::init(status);
 
77
 
 
78
    reset();
 
79
}
 
80
 
 
81
 
 
82
 
 
83
void RS_ActionDrawArc::trigger() {
 
84
    RS_PreviewActionInterface::trigger();
 
85
 
 
86
    RS_Arc* arc = new RS_Arc(container,
 
87
                             data);
 
88
    arc->setLayerToActive();
 
89
    arc->setPenToActive();
 
90
    container->addEntity(arc);
 
91
 
 
92
    // upd. undo list:
 
93
    if (document!=NULL) {
 
94
        document->startUndoCycle();
 
95
        document->addUndoable(arc);
 
96
        document->endUndoCycle();
 
97
    }
 
98
 
 
99
        graphicView->redraw(RS2::RedrawDrawing);
 
100
    graphicView->moveRelativeZero(arc->getCenter());
 
101
 
 
102
    setStatus(SetCenter);
 
103
    reset();
 
104
 
 
105
    RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d",
 
106
                    arc->getId());
 
107
}
 
108
 
 
109
 
 
110
 
 
111
void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent* e) {
 
112
    RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
 
113
 
 
114
    RS_Vector mouse = snapPoint(e);
 
115
    switch (getStatus()) {
 
116
    case SetCenter:
 
117
        data.center = mouse;
 
118
        break;
 
119
 
 
120
    case SetRadius:
 
121
        if (data.center.valid) {
 
122
            data.radius = data.center.distanceTo(mouse);
 
123
            deletePreview();
 
124
            preview->addEntity(new RS_Circle(preview,
 
125
                                             RS_CircleData(data.center,
 
126
                                                           data.radius)));
 
127
            drawPreview();
 
128
        }
 
129
        break;
 
130
 
 
131
    case SetAngle1:
 
132
        data.angle1 = data.center.angleTo(mouse);
 
133
        if (data.reversed) {
 
134
            data.angle2 = RS_Math::correctAngle(data.angle1-M_PI/3);
 
135
        } else {
 
136
            data.angle2 = RS_Math::correctAngle(data.angle1+M_PI/3);
 
137
        }
 
138
        deletePreview();
 
139
        preview->addEntity(new RS_Arc(preview,
 
140
                                      data));
 
141
        drawPreview();
 
142
        break;
 
143
 
 
144
    case SetAngle2:
 
145
        data.angle2 = data.center.angleTo(mouse);
 
146
        deletePreview();
 
147
        preview->addEntity(new RS_Arc(preview,
 
148
                                      data));
 
149
        drawPreview();
 
150
        break;
 
151
 
 
152
    case SetIncAngle:
 
153
        data.angle2 = data.angle1 + data.center.angleTo(mouse);
 
154
        deletePreview();
 
155
        preview->addEntity(new RS_Arc(preview,
 
156
                                      data));
 
157
        drawPreview();
 
158
        break;
 
159
 
 
160
    case SetChordLength: {
 
161
            double x = data.center.distanceTo(mouse);
 
162
            if (fabs(x/(2*data.radius))<=1.0) {
 
163
                data.angle2 = data.angle1 + asin(x/(2*data.radius)) * 2;
 
164
                deletePreview();
 
165
                preview->addEntity(new RS_Arc(preview,
 
166
                                              data));
 
167
                drawPreview();
 
168
            }
 
169
        }
 
170
        break;
 
171
 
 
172
    default:
 
173
        break;
 
174
 
 
175
    }
 
176
 
 
177
    RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
 
178
}
 
179
 
 
180
 
 
181
 
 
182
void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent* e) {
 
183
    if (e->button()==Qt::LeftButton) {
 
184
        RS_CoordinateEvent ce(snapPoint(e));
 
185
        coordinateEvent(&ce);
 
186
    } else if (e->button()==Qt::RightButton) {
 
187
        deletePreview();
 
188
        init(getStatus()-1);
 
189
    }
 
190
}
 
191
 
 
192
 
 
193
 
 
194
void RS_ActionDrawArc::coordinateEvent(RS_CoordinateEvent* e) {
 
195
    if (e==NULL) {
 
196
        return;
 
197
    }
 
198
    RS_Vector mouse = e->getCoordinate();
 
199
 
 
200
    switch (getStatus()) {
 
201
    case SetCenter:
 
202
        data.center = mouse;
 
203
        graphicView->moveRelativeZero(mouse);
 
204
        setStatus(SetRadius);
 
205
        break;
 
206
 
 
207
    case SetRadius:
 
208
        if (data.center.valid) {
 
209
            data.radius = data.center.distanceTo(mouse);
 
210
        }
 
211
        setStatus(SetAngle1);
 
212
        break;
 
213
 
 
214
    case SetAngle1:
 
215
        data.angle1 = data.center.angleTo(mouse);
 
216
        setStatus(SetAngle2);
 
217
        break;
 
218
 
 
219
    case SetAngle2:
 
220
        data.angle2 = data.center.angleTo(mouse);
 
221
        trigger();
 
222
        break;
 
223
 
 
224
    case SetIncAngle:
 
225
        data.angle2 = data.angle1 + data.center.angleTo(mouse);
 
226
        trigger();
 
227
        break;
 
228
 
 
229
    case SetChordLength: {
 
230
            double x = data.center.distanceTo(mouse);
 
231
            if (fabs(x/(2*data.radius))<=1.0) {
 
232
                data.angle2 = data.angle1 + asin(x/(2*data.radius)) * 2;
 
233
                trigger();
 
234
            }
 
235
        }
 
236
        break;
 
237
 
 
238
    default:
 
239
        break;
 
240
    }
 
241
}
 
242
 
 
243
 
 
244
 
 
245
void RS_ActionDrawArc::commandEvent(RS_CommandEvent* e) {
 
246
    QString c = e->getCommand().toLower();
 
247
 
 
248
    if (RS_COMMANDS->checkCommand("help", c)) {
 
249
        if (RS_DIALOGFACTORY!=NULL) {
 
250
            RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
 
251
                                             + getAvailableCommands().join(", "));
 
252
        }
 
253
        return;
 
254
    }
 
255
 
 
256
    if (RS_COMMANDS->checkCommand("reversed", c)) {
 
257
        e->accept();
 
258
        setReversed(!isReversed());
 
259
 
 
260
        if (RS_DIALOGFACTORY!=NULL) {
 
261
            RS_DIALOGFACTORY->requestOptions(this, true, true);
 
262
        }
 
263
        return;
 
264
    }
 
265
 
 
266
    switch (getStatus()) {
 
267
 
 
268
    case SetRadius: {
 
269
            bool ok;
 
270
            double r = RS_Math::eval(c, &ok);
 
271
            if (ok==true) {
 
272
                data.radius = r;
 
273
                setStatus(SetAngle1);
 
274
            } else {
 
275
                if (RS_DIALOGFACTORY!=NULL) {
 
276
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
277
                }
 
278
            }
 
279
        }
 
280
        break;
 
281
 
 
282
    case SetAngle1: {
 
283
            bool ok;
 
284
            double a = RS_Math::eval(c, &ok);
 
285
            if (ok==true) {
 
286
                data.angle1 = RS_Math::deg2rad(a);
 
287
                setStatus(SetAngle2);
 
288
            } else {
 
289
                if (RS_DIALOGFACTORY!=NULL) {
 
290
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
291
                }
 
292
            }
 
293
        }
 
294
        break;
 
295
 
 
296
    case SetAngle2: {
 
297
            if (RS_COMMANDS->checkCommand("angle", c)) {
 
298
                setStatus(SetIncAngle);
 
299
            } else if (RS_COMMANDS->checkCommand("chord length", c)) {
 
300
                setStatus(SetChordLength);
 
301
            } else {
 
302
                bool ok;
 
303
                double a = RS_Math::eval(c, &ok);
 
304
                if (ok==true) {
 
305
                    data.angle2 = RS_Math::deg2rad(a);
 
306
                    trigger();
 
307
                } else {
 
308
                    if (RS_DIALOGFACTORY!=NULL) {
 
309
                        RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
310
                    }
 
311
                }
 
312
            }
 
313
        }
 
314
        break;
 
315
 
 
316
    case SetIncAngle: {
 
317
            bool ok;
 
318
            double a = RS_Math::eval(c, &ok);
 
319
            if (ok==true) {
 
320
                data.angle2 = data.angle1 + RS_Math::deg2rad(a);
 
321
                trigger();
 
322
            } else {
 
323
                if (RS_DIALOGFACTORY!=NULL) {
 
324
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
325
                }
 
326
            }
 
327
        }
 
328
        break;
 
329
 
 
330
    case SetChordLength: {
 
331
            bool ok;
 
332
            double l = RS_Math::eval(c, &ok);
 
333
            if (ok==true) {
 
334
                if (fabs(l/(2*data.radius))<=1.0) {
 
335
                    data.angle2 = data.angle1 + asin(l/(2*data.radius)) * 2;
 
336
                    trigger();
 
337
                } else {
 
338
                    if (RS_DIALOGFACTORY!=NULL) {
 
339
                        RS_DIALOGFACTORY->commandMessage(
 
340
                            tr("Not a valid chord length"));
 
341
                    }
 
342
                }
 
343
            } else {
 
344
                if (RS_DIALOGFACTORY!=NULL) {
 
345
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
346
                }
 
347
            }
 
348
        }
 
349
        break;
 
350
 
 
351
    default:
 
352
        break;
 
353
    }
 
354
}
 
355
 
 
356
 
 
357
 
 
358
QStringList RS_ActionDrawArc::getAvailableCommands() {
 
359
    QStringList cmd;
 
360
    cmd += RS_COMMANDS->command("reversed");
 
361
    return cmd;
 
362
}
 
363
 
 
364
 
 
365
void RS_ActionDrawArc::updateMouseButtonHints() {
 
366
    if (RS_DIALOGFACTORY!=NULL) {
 
367
        switch (getStatus()) {
 
368
        case SetCenter:
 
369
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
 
370
            break;
 
371
        case SetRadius:
 
372
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
 
373
            break;
 
374
        case SetAngle1:
 
375
            RS_DIALOGFACTORY->updateMouseWidget(
 
376
                tr("Specify start angle:"), tr("Back"));
 
377
            break;
 
378
        case SetAngle2:
 
379
            RS_DIALOGFACTORY->updateMouseWidget(
 
380
                tr("Specify end angle or [angle/chord length]"),
 
381
                tr("Back"));
 
382
            break;
 
383
        case SetIncAngle:
 
384
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
 
385
                                                tr("Back"));
 
386
            break;
 
387
        case SetChordLength:
 
388
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
 
389
                                                tr("Back"));
 
390
            break;
 
391
        default:
 
392
            RS_DIALOGFACTORY->updateMouseWidget("", "");
 
393
            break;
 
394
        }
 
395
    }
 
396
}
 
397
 
 
398
 
 
399
 
 
400
void RS_ActionDrawArc::showOptions() {
 
401
    RS_ActionInterface::showOptions();
 
402
 
 
403
    if (RS_DIALOGFACTORY!=NULL) {
 
404
        RS_DIALOGFACTORY->requestOptions(this, true);
 
405
    }
 
406
}
 
407
 
 
408
 
 
409
 
 
410
void RS_ActionDrawArc::hideOptions() {
 
411
    RS_ActionInterface::hideOptions();
 
412
 
 
413
    if (RS_DIALOGFACTORY!=NULL) {
 
414
        RS_DIALOGFACTORY->requestOptions(this, false);
 
415
    }
 
416
}
 
417
 
 
418
 
 
419
 
 
420
void RS_ActionDrawArc::updateMouseCursor() {
 
421
    graphicView->setMouseCursor(RS2::CadCursor);
 
422
}
 
423
 
 
424
 
 
425
 
 
426
//void RS_ActionDrawArc::updateToolBar() {
 
427
//    if (RS_DIALOGFACTORY!=NULL) {
 
428
//        if (isFinished()) {
 
429
//            RS_DIALOGFACTORY->resetToolBar();
 
430
//        }else{
 
431
//            RS_DIALOGFACTORY->showCadToolBar(rtti());
 
432
//        }
 
433
//    }
 
434
//}
 
435
 
 
436
 
 
437
// EOF
 
438