~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/actions/rs_actiondrawcircletan2.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
 * Draw circle by foci and a point on circle
 
4
 
 
5
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
 
6
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
 
7
 
 
8
This program is free software; you can redistribute it and/or
 
9
modify it under the terms of the GNU General Public License
 
10
as published by the Free Software Foundation; either version 2
 
11
of the License, or (at your option) any later version.
 
12
 
 
13
This program is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with this program; if not, write to the Free Software
 
20
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
21
**********************************************************************/
 
22
 
 
23
#include "rs_actiondrawcircletan2.h"
 
24
 
 
25
#include <QAction>
 
26
#include "rs_dialogfactory.h"
 
27
#include "rs_graphicview.h"
 
28
#include "rs_commandevent.h"
 
29
 
 
30
/**
 
31
 * Constructor.
 
32
 *
 
33
 */
 
34
RS_ActionDrawCircleTan2::RS_ActionDrawCircleTan2(
 
35
        RS_EntityContainer& container,
 
36
        RS_GraphicView& graphicView)
 
37
    :RS_PreviewActionInterface("Draw circle inscribed",
 
38
                               container, graphicView),
 
39
      cData(RS_Vector(0.,0.),1.),
 
40
      enTypeList()
 
41
{
 
42
    //    supported types
 
43
    enTypeList<<RS2::EntityLine<<RS2::EntityArc<<RS2::EntityCircle;
 
44
}
 
45
 
 
46
 
 
47
 
 
48
RS_ActionDrawCircleTan2::~RS_ActionDrawCircleTan2() {
 
49
}
 
50
 
 
51
 
 
52
 
 
53
QAction* RS_ActionDrawCircleTan2::createGUIAction(RS2::ActionType /*type*/, QObject* /*parent*/) {
 
54
    QAction* action;
 
55
 
 
56
    action = new QAction(tr("Circle Tangential &2"), NULL);
 
57
    action->setIcon(QIcon(":/extui/circletan2.png"));
 
58
    return action;
 
59
}
 
60
 
 
61
void RS_ActionDrawCircleTan2::init(int status) {
 
62
    RS_PreviewActionInterface::init(status);
 
63
    if(status>=0) {
 
64
        RS_Snapper::suspend();
 
65
    }
 
66
 
 
67
    if (status==SetCircle1) {
 
68
        circles.clear();
 
69
    }
 
70
}
 
71
 
 
72
 
 
73
void RS_ActionDrawCircleTan2::finish(bool updateTB){
 
74
    if(circles.size()>0){
 
75
        for(int i=0;i<circles.size();i++) {
 
76
            if(circles.at(i) != NULL) circles.at(i)->setHighlighted(false);
 
77
        }
 
78
        graphicView->redraw(RS2::RedrawDrawing);
 
79
        circles.clear();
 
80
    }
 
81
    RS_PreviewActionInterface::finish(updateTB);
 
82
}
 
83
 
 
84
//void RS_ActionDrawCircleTan2::finish(bool updateTB){
 
85
////    for(int i=0;i<circles.size();i++) circles[i]->setHighlighted(false);
 
86
////    graphicView->redraw(RS2::RedrawDrawing);
 
87
////    circles.clear();
 
88
//    RS_PreviewActionInterface::finish(updateTB);
 
89
//}
 
90
 
 
91
 
 
92
void RS_ActionDrawCircleTan2::trigger() {
 
93
    //    std::cout<<__FILE__<<" : "<<__FUNCTION__<<" : line "<<__LINE__<<std::endl;
 
94
    //    std::cout<<"begin"<<std::endl;
 
95
 
 
96
    RS_PreviewActionInterface::trigger();
 
97
 
 
98
 
 
99
    RS_Circle* circle=new RS_Circle(container, cData);
 
100
 
 
101
    container->addEntity(circle);
 
102
 
 
103
    // upd. undo list:
 
104
    if (document!=NULL) {
 
105
        document->startUndoCycle();
 
106
        document->addUndoable(circle);
 
107
        document->endUndoCycle();
 
108
    }
 
109
 
 
110
    for(int i=0;i<circles.size();i++) circles[i]->setHighlighted(false);
 
111
    graphicView->redraw(RS2::RedrawDrawing);
 
112
    //    drawSnapper();
 
113
 
 
114
    circles.clear();
 
115
    setStatus(SetCircle1);
 
116
 
 
117
    RS_DEBUG->print("RS_ActionDrawCircleTan2::trigger():"
 
118
                    " entity added: %d", circle->getId());
 
119
}
 
120
 
 
121
 
 
122
 
 
123
void RS_ActionDrawCircleTan2::mouseMoveEvent(QMouseEvent* e) {
 
124
    RS_DEBUG->print("RS_ActionDrawCircleTan2::mouseMoveEvent begin");
 
125
 
 
126
    switch(getStatus() ){
 
127
    case SetCenter: {
 
128
        //        RS_Entity*  en = catchEntity(e, enTypeList, RS2::ResolveAll);
 
129
        coord= graphicView->toGraph(e->x(), e->y());
 
130
        //        circles[getStatus()]=static_cast<RS_Line*>(en);
 
131
        if(preparePreview()) {
 
132
            deletePreview();
 
133
            RS_Circle* e=new RS_Circle(preview, cData);
 
134
            preview->addEntity(e);
 
135
            drawPreview();
 
136
        }
 
137
    }
 
138
        break;
 
139
    default:
 
140
        break;
 
141
    }
 
142
    RS_DEBUG->print("RS_ActionDrawCircleTan2::mouseMoveEvent end");
 
143
}
 
144
 
 
145
void RS_ActionDrawCircleTan2::setRadius(const double& r)
 
146
{
 
147
    cData.radius=r;
 
148
    if(getStatus() == SetCenter){
 
149
        RS_Circle c(NULL,cData);
 
150
        centers=c.createTan2(circles,cData.radius);
 
151
    }
 
152
}
 
153
 
 
154
bool RS_ActionDrawCircleTan2::getCenters(){
 
155
    if(getStatus() != SetCircle2) return false;
 
156
    RS_Circle c(NULL,cData);
 
157
    centers=c.createTan2(circles,cData.radius);
 
158
    valid= (centers.size()>0);
 
159
    return valid;
 
160
}
 
161
 
 
162
bool RS_ActionDrawCircleTan2::preparePreview(){
 
163
    if(valid) {
 
164
        cData.center=centers.getClosest(coord);
 
165
    }
 
166
    return valid;
 
167
}
 
168
 
 
169
RS_Entity* RS_ActionDrawCircleTan2::catchCircle(QMouseEvent* e) {
 
170
    RS_Entity* ret=NULL;
 
171
    RS_Entity*  en = catchEntity(e,enTypeList, RS2::ResolveAll);
 
172
    if(en == NULL) return ret;
 
173
    if(en->isVisible()==false) return ret;
 
174
    for(int i=0;i<getStatus();i++) {
 
175
        if(en->getId() == circles[i]->getId()) return ret; //do not pull in the same line again
 
176
    }
 
177
    if(en->getParent() != NULL) {
 
178
        if ( en->getParent()->rtti() == RS2::EntityInsert         /**Insert*/
 
179
             || en->getParent()->rtti() == RS2::EntitySpline
 
180
             || en->getParent()->rtti() == RS2::EntityMText        /**< Text 15*/
 
181
             || en->getParent()->rtti() == RS2::EntityText         /**< Text 15*/
 
182
             || en->getParent()->rtti() == RS2::EntityDimAligned   /**< Aligned Dimension */
 
183
             || en->getParent()->rtti() == RS2::EntityDimLinear    /**< Linear Dimension */
 
184
             || en->getParent()->rtti() == RS2::EntityDimRadial    /**< Radial Dimension */
 
185
             || en->getParent()->rtti() == RS2::EntityDimDiametric /**< Diametric Dimension */
 
186
             || en->getParent()->rtti() == RS2::EntityDimAngular   /**< Angular Dimension */
 
187
             || en->getParent()->rtti() == RS2::EntityDimLeader    /**< Leader Dimension */
 
188
             ){
 
189
            return ret;
 
190
        }
 
191
    }
 
192
    return en;
 
193
}
 
194
 
 
195
void RS_ActionDrawCircleTan2::mouseReleaseEvent(QMouseEvent* e) {
 
196
    // Proceed to next status
 
197
    if (e->button()==Qt::LeftButton) {
 
198
 
 
199
        switch (getStatus()) {
 
200
        case SetCircle1:
 
201
        case SetCircle2: {
 
202
            RS_Entity*  en = catchCircle(e);
 
203
            if (en==NULL) return;
 
204
            circles.resize(getStatus());
 
205
            circles.push_back(static_cast<RS_AtomicEntity*>(en));
 
206
            if(getStatus()==SetCircle1 || getCenters()){
 
207
                circles.at(circles.size()-1)->setHighlighted(true);
 
208
                graphicView->redraw(RS2::RedrawDrawing);
 
209
                setStatus(getStatus()+1);
 
210
            }
 
211
        }
 
212
            break;
 
213
        case SetCenter:
 
214
            coord= graphicView->toGraph(e->x(), e->y());
 
215
            if( preparePreview()) trigger();
 
216
            break;
 
217
 
 
218
        default:
 
219
            break;
 
220
        }
 
221
    } else if (e->button()==Qt::RightButton) {
 
222
        // Return to last status:
 
223
        if(getStatus()>0){
 
224
            circles[getStatus()-1]->setHighlighted(false);
 
225
            circles.pop_back();
 
226
            graphicView->redraw(RS2::RedrawDrawing);
 
227
            deletePreview();
 
228
        }
 
229
        init(getStatus()-1);
 
230
    }
 
231
}
 
232
 
 
233
 
 
234
//void RS_ActionDrawCircleTan2::coordinateEvent(RS_CoordinateEvent* e) {
 
235
 
 
236
//}
 
237
 
 
238
//fixme, support command line
 
239
 
 
240
/*
 
241
void RS_ActionDrawCircleTan2::commandEvent(RS_CommandEvent* e) {
 
242
    QString c = e->getCommand().toLower();
 
243
 
 
244
    if (checkCommand("help", c)) {
 
245
        if (RS_DIALOGFACTORY!=NULL) {
 
246
            RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
 
247
                                             + getAvailableCommands().join(", "));
 
248
        }
 
249
        return;
 
250
    }
 
251
 
 
252
    switch (getStatus()) {
 
253
    case SetFocus1: {
 
254
            bool ok;
 
255
            double m = RS_Math::eval(c, &ok);
 
256
            if (ok==true) {
 
257
                ratio = m / major.magnitude();
 
258
                if (!isArc) {
 
259
                    trigger();
 
260
                } else {
 
261
                    setStatus(SetAngle1);
 
262
                }
 
263
            } else {
 
264
                if (RS_DIALOGFACTORY!=NULL) {
 
265
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
266
                }
 
267
            }
 
268
        }
 
269
        break;
 
270
 
 
271
    case SetAngle1: {
 
272
            bool ok;
 
273
            double a = RS_Math::eval(c, &ok);
 
274
            if (ok==true) {
 
275
                angle1 = RS_Math::deg2rad(a);
 
276
                setStatus(SetAngle2);
 
277
            } else {
 
278
                if (RS_DIALOGFACTORY!=NULL) {
 
279
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
280
                }
 
281
            }
 
282
        }
 
283
        break;
 
284
 
 
285
    case SetAngle2: {
 
286
            bool ok;
 
287
            double a = RS_Math::eval(c, &ok);
 
288
            if (ok==true) {
 
289
                angle2 = RS_Math::deg2rad(a);
 
290
                trigger();
 
291
            } else {
 
292
                if (RS_DIALOGFACTORY!=NULL) {
 
293
                    RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
 
294
                }
 
295
            }
 
296
        }
 
297
        break;
 
298
 
 
299
    default:
 
300
        break;
 
301
    }
 
302
}
 
303
*/
 
304
 
 
305
 
 
306
void RS_ActionDrawCircleTan2::showOptions() {
 
307
    RS_DEBUG->print("RS_ActionDrawCircleTan2::showOptions");
 
308
    if(RS_DIALOGFACTORY != NULL){
 
309
        RS_ActionInterface::showOptions();
 
310
 
 
311
        RS_DIALOGFACTORY->requestOptions(this, true);
 
312
    }
 
313
    RS_DEBUG->print("RS_ActionDrawCircleTan2::showOptions: OK");
 
314
}
 
315
 
 
316
 
 
317
 
 
318
void RS_ActionDrawCircleTan2::hideOptions() {
 
319
    if(RS_DIALOGFACTORY != NULL){
 
320
        RS_ActionInterface::hideOptions();
 
321
 
 
322
        RS_DIALOGFACTORY->requestOptions(this, false);
 
323
    }
 
324
}
 
325
 
 
326
 
 
327
QStringList RS_ActionDrawCircleTan2::getAvailableCommands() {
 
328
    QStringList cmd;
 
329
    return cmd;
 
330
}
 
331
 
 
332
 
 
333
 
 
334
void RS_ActionDrawCircleTan2::updateMouseButtonHints() {
 
335
    if (RS_DIALOGFACTORY!=NULL) {
 
336
        switch (getStatus()) {
 
337
        case SetCircle1:
 
338
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first line/arc/circle"),
 
339
                                                tr("Cancel"));
 
340
            break;
 
341
 
 
342
        case SetCircle2:
 
343
            RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second line/arc/circle"),
 
344
                                                tr("Back"));
 
345
            break;
 
346
 
 
347
        case SetCenter:
 
348
            RS_DIALOGFACTORY->updateMouseWidget(tr("Select the center of the tangent circle"),
 
349
                                                tr("Back"));
 
350
            break;
 
351
        default:
 
352
            RS_DIALOGFACTORY->updateMouseWidget("", "");
 
353
            break;
 
354
        }
 
355
    }
 
356
}
 
357
 
 
358
 
 
359
 
 
360
void RS_ActionDrawCircleTan2::updateMouseCursor() {
 
361
    graphicView->setMouseCursor(RS2::CadCursor);
 
362
}
 
363
 
 
364
 
 
365
 
 
366
//void RS_ActionDrawCircleTan2::updateToolBar() {
 
367
//    if (RS_DIALOGFACTORY!=NULL) {
 
368
//        if (isFinished()) {
 
369
//            RS_DIALOGFACTORY->resetToolBar();
 
370
//        }
 
371
//    }
 
372
//}
 
373
 
 
374
// EOF