FreeCAD

Форк
0
/
QGEPath.cpp 
409 строк · 12.0 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2019 WandererFan <wandererfan@gmail.com>                *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <QGraphicsScene>
26
# include <QGraphicsSceneHoverEvent>
27
# include <QKeyEvent>
28
# include <QPainterPath>
29
# include <QPainterPathStroker>
30
#endif
31

32
#include <Base/Console.h>
33
#include <Mod/TechDraw/App/DrawLeaderLine.h>
34
#include <Mod/TechDraw/App/DrawUtil.h>
35

36
#include "QGEPath.h"
37
#include "PreferencesGui.h"
38
#include "QGILeaderLine.h"
39
#include "QGIPrimPath.h"
40
#include "QGIVertex.h"
41
#include "QGIView.h"
42
#include "Rez.h"
43
#include "ZVALUE.h"
44

45

46
using namespace TechDrawGui;
47
using namespace TechDraw;
48

49
QGMarker::QGMarker(int idx) : QGIVertex(idx),
50
    m_dragging(false)
51
{
52
//    Base::Console().Message("QGMarker::QGMarker(%d)\n", idx);
53
    setFlag(QGraphicsItem::ItemIsMovable, true);
54
}
55

56
void QGMarker::mousePressEvent(QGraphicsSceneMouseEvent * event)
57
{
58
//    Base::Console().Message("QGMarker::mousePressEvent() - focustype: %d\n",
59
//                            scene()->focusItem()->type() - QGraphicsItem::UserType);
60

61
    if (event->button() == Qt::RightButton) {    //we're done
62
        Q_EMIT endEdit();
63
        event->accept();
64
        return;
65
    } else if(scene() && this == scene()->mouseGrabberItem()) {
66
        //start dragging
67
        m_dragging = true;
68
        Q_EMIT dragging(pos(), getProjIndex());      //pass center of marker[i] to epath
69
    }
70
    QGIVertex::mousePressEvent(event);
71
}
72

73
void QGMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
74
{
75
    if (event->button() == Qt::RightButton) {    //we're done
76
        Q_EMIT endEdit();
77
        m_dragging = false;
78
        return;
79
    }
80

81
    if(this->scene() && this == this->scene()->mouseGrabberItem()) {
82
        if (m_dragging) {
83
            m_dragging = false;
84
            setSelected(false);
85
            Q_EMIT dragFinished(pos(), getProjIndex());      //pass center of marker[i] to epath
86
        }
87
    }
88
    QGIVertex::mouseReleaseEvent(event);
89
}
90

91
void QGMarker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
92
{
93
//    Base::Console().Message("QGMarker::mouseDoubleClickEvent(%d)\n", getProjIndex());
94
    if (event->button() == Qt::RightButton) {    //we're done
95
        Q_EMIT endEdit();
96
        return;
97
    }
98
    QGIVertex::mouseDoubleClickEvent(event);
99
}
100

101
void QGMarker::keyPressEvent(QKeyEvent * event)
102
{
103
//    Base::Console().Message("QGMarker::keyPressEvent(%d)\n", getProjIndex());
104
    if (event->key() == Qt::Key_Escape) {
105
        Q_EMIT endEdit();
106
    }
107
    QGIVertex::keyPressEvent(event);
108
}
109

110
void QGMarker::setRadius(float radius)
111
{
112
    //TODO:: implement different marker shapes. circle, square, triangle, ???
113
    //if (m_markerShape == Circle) { ...
114
    //setRect(QRectF) for rectangular markers
115
    m_radius = radius;
116
    QPainterPath p;
117
    p.addRect(-radius/2.0, -radius/2.0, radius, radius);
118
    setPath(p);
119
}
120

121
//******************************************************************************
122

123
QGEPath::QGEPath(QGILeaderLine* leader) :
124
    m_scale(1.0),
125
    m_inEdit(false),
126
    m_parentLeader(leader),
127
    m_startAdj(0.0),
128
    m_endAdj(0.0)
129
{
130
    setHandlesChildEvents(false);
131
    setAcceptHoverEvents(true);
132
    setFlag(QGraphicsItem::ItemIsSelectable, true);
133
    setFlag(QGraphicsItem::ItemIsMovable, false);
134
    setFlag(QGraphicsItem::ItemSendsScenePositionChanges, false);
135
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
136

137
    m_ghost = new QGIPrimPath();       //drawing/editing line
138
    m_ghost->setParentItem(this);
139
    m_ghost->setNormalColor(Qt::red);
140
    m_ghost->setStyle(Qt::DashLine);
141
    m_ghost->setPrettyNormal();
142
    m_ghost->hide();
143

144
}
145

146
QVariant QGEPath::itemChange(GraphicsItemChange change, const QVariant &value)
147
{
148
//    Base::Console().Message("QGEP::itemChange(%d) - type: %d\n", change, type() - QGraphicsItem::UserType);
149
    if (change == ItemSelectedHasChanged && scene()) {
150
        if(isSelected()) {
151
            Q_EMIT selected(true);
152
            setPrettySel();
153
        } else {
154
            Q_EMIT selected(false);
155
            setPrettyNormal();
156
        }
157
    }
158
    return QGIPrimPath::itemChange(change, value);
159
}
160

161
void QGEPath::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
162
{
163
    Q_EMIT hover(true);
164
    if (!isSelected()) {
165
        setPrettyPre();
166
    }
167
    QGIPrimPath::hoverEnterEvent(event);
168
}
169

170
void QGEPath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
171
{
172
    QGIView *view = dynamic_cast<QGIView *> (parentItem());
173
    assert(view);
174
    Q_UNUSED(view);
175

176
    Q_EMIT hover(false);
177
    QGraphicsItem* parent = parentItem();
178
    bool parentSel(false);
179
    if (parent) {
180
        parentSel = parent->isSelected();
181
    }
182
    if (!parentSel  && !isSelected()) {
183
        setPrettyNormal();
184
    }
185
    QGraphicsPathItem::hoverLeaveEvent(event);
186
//    QGIPrimPath::hoverLeaveEvent(event);  //QGIPP::hoverleave will reset pretty to normal
187
}
188

189
void QGEPath::startPathEdit(std::vector<QPointF> pathPoints)
190
{
191
//    Base::Console().Message("QGEPath::startPathEdit()\n");
192
    inEdit(true);
193
    m_ghostPoints = pathPoints;
194
    showMarkers(m_ghostPoints);
195
}
196

197
void QGEPath::showMarkers(std::vector<QPointF> points)
198
{
199
//    Base::Console().Message("QGEPath::showMarkers()\n");
200
    if (!inEdit()) {
201
        return;
202
    }
203

204
    if (points.empty()) {
205
        Base::Console().Message("QGEP::showMarkers - no deltas\n");
206
        return;
207
    }
208

209
    clearMarkers();
210
//    dumpGhostPoints("QGEPath::showMarkers");
211

212
    int pointDx = 0;
213
    for (auto& p: points) {
214
        QGMarker* v = new QGMarker(pointDx);
215
        v->setFlag(QGraphicsItem::ItemIsMovable, true);
216
        v->setFlag(QGraphicsItem::ItemIsFocusable, true);
217
        v->setParentItem(this);
218
        QObject::connect(
219
            v, &QGMarker::dragFinished,
220
            this, &QGEPath::onDragFinished
221
           );
222
        QObject::connect(
223
            v, &QGMarker::dragging,
224
            this, &QGEPath::onDragging
225
           );
226
        QObject::connect(
227
            v, &QGMarker::doubleClick,
228
            this, &QGEPath::onDoubleClick
229
           );
230
        QObject::connect(
231
            v, &QGMarker::endEdit,
232
            this, &QGEPath::onEndEdit
233
           );
234
//TODO: double r = getMarkerSize();
235
//      v->setRadius(r);
236
        v->setRadius(50.0);
237
        v->setNormalColor(PreferencesGui::getAccessibleQColor(QColor(Qt::black)));
238
        v->setZValue(ZVALUE::VERTEX);
239
        v->setPos(p);
240
        v->show();
241

242
        m_markers.push_back(v);
243
        pointDx++;
244
    }
245
}
246

247
void QGEPath::clearMarkers()
248
{
249
//    Base::Console().Message("QGEPath::clearMarkers()\n");
250
    if (m_markers.empty()) {
251
        return;
252
    }
253
    for (auto& m: m_markers) {
254
        if (m) {
255
            m->hide();
256
            QGraphicsScene* s = m->scene();
257
            if (s) {
258
                s->removeItem(m);           //should this be setParentItem(nullptr) instead??
259
            }
260
            delete m;
261
        }
262
    }
263
    m_markers.clear();
264
}
265

266
// end of node marker drag
267
void QGEPath::onDragFinished(QPointF dragEndPos, int markerIndex)
268
{
269
//    Base::Console().Message("QGEPath::onDragFinished(%s, %d)\n",
270
//                            TechDraw::DrawUtil::formatVector(dragEndPos).c_str(),
271
//                            markerIndex);
272
    if ((int) m_ghostPoints.size() > markerIndex) {
273
        m_ghostPoints.at(markerIndex) = dragEndPos;
274
    }
275
    drawGhost();
276
}
277

278
void QGEPath::onDragging(QPointF pos, int markerIndex)
279
{
280
     Q_UNUSED(pos);
281
     Q_UNUSED(markerIndex);
282
     //Q_EMIT dragging(
283
    //TODO: could "live update" line during Drag
284
}
285

286
//this is for double click on a marker
287
void QGEPath::onDoubleClick(QPointF pos, int markerIndex)
288
{
289
    Q_UNUSED(pos);
290
    Q_UNUSED(markerIndex);
291
//    Base::Console().Message("QGEPath::onDoubleClick()\n");
292
    onEndEdit();
293
}
294

295
void QGEPath::onEndEdit()
296
{
297
//    Base::Console().Message("QGEPath::onEndEdit()\n");
298
    if (m_ghost) {
299
        scene()->removeItem(m_ghost);   //stop ghost from messing up brect
300
    }
301
    inEdit(false);
302

303
    updateParent();         //Q_EMIT pointsUpdated(m_featDeltas) ==> onLineEditComplete  <<<
304
    clearMarkers();
305
}
306

307
std::vector<QPointF> QGEPath::getDeltasFromLeader()
308
{
309
    std::vector<QPointF> qDeltas;
310
    if (!m_parentLeader) {
311
        Base::Console().Message("QGEP::getDeltasFromLeader - m_parentLeader is nullptr\n");
312
        return qDeltas;
313
    }
314

315
    DrawLeaderLine* featLeader = m_parentLeader->getFeature();
316
    if (!featLeader) {
317
        Base::Console().Message("QGEP::getDeltasFromLeader - featLeader is nullptr\n");
318
        return  qDeltas;
319
    }
320

321
    std::vector<Base::Vector3d> vDeltas = featLeader->WayPoints.getValues();
322
    for (auto& d: vDeltas) {
323
        Base::Vector3d vTemp = Rez::guiX(d);
324
        QPointF temp(vTemp.x, -vTemp.y);
325
        qDeltas.push_back(temp);
326
    }
327
    if (qDeltas.empty()) {
328
        Base::Console().Warning("QGEPath::getDeltasFromLeader - no points\n");
329
    }
330
    return qDeltas;
331
}
332

333
//announce points editing is finished
334
void QGEPath::updateParent()
335
{
336
//    Base::Console().Message("QGEPath::updateParent() - inEdit: %d pts: %d\n", inEdit(), m_ghostPoints.size());
337
//    dumpGhostPoints("QGEP::updateParent");
338
    QPointF attach = m_ghostPoints.front();
339
    if (!inEdit()) {
340
        Q_EMIT pointsUpdated(attach, m_ghostPoints);
341
    }
342
}
343

344
//the ghost is the red line drawn when creating or editing the Leader points
345
void QGEPath::drawGhost()
346
{
347
//    Base::Console().Message("QGEPath::drawGhost()\n");
348
    if (!m_ghost->scene()) {
349
        m_ghost->setParentItem(this);
350
    }
351
    QPainterPath qpp;
352
    qpp.moveTo(m_ghostPoints.front());
353
    for (int i = 1; i < (int)m_ghostPoints.size(); i++) {
354
        qpp.lineTo(m_ghostPoints.at(i));
355
    }
356
    m_ghost->setPath(qpp);
357
    m_ghost->show();
358
}
359

360
void QGEPath::setStartAdjust(double adj)
361
{
362
    m_startAdj = Rez::guiX(adj);
363
}
364

365
void QGEPath::setEndAdjust(double adj)
366
{
367
    m_endAdj = Rez::guiX(adj);
368
}
369

370
QRectF QGEPath::boundingRect() const
371
{
372
    return shape().controlPointRect();
373
}
374

375
QPainterPath QGEPath::shape() const
376
{
377
    QPainterPath outline;
378
    QPainterPathStroker stroker;
379
    stroker.setWidth(getEdgeFuzz() * 2.0);
380
    outline = stroker.createStroke(path()).simplified();
381
    return outline;
382
}
383

384
 double QGEPath::getEdgeFuzz() const
385
{
386
    return PreferencesGui::edgeFuzz();
387
}
388

389
void QGEPath::dumpGhostPoints(const char* text)
390
{
391
    int idb = 0;
392
    for (auto& d: m_ghostPoints) {
393
        Base::Console().Message("%s - point: %d %s\n", text,
394
                                 idb, TechDraw::DrawUtil::formatVector(d).c_str());
395
        idb++;
396
    }
397
}
398

399
void QGEPath::dumpMarkerPos(const char* text)
400
{
401
    int idb = 0;
402
    for (auto& m: m_markers) {
403
        Base::Console().Message("QGEP - %s - markerPos: %d %s\n", text,
404
                                 idb, TechDraw::DrawUtil::formatVector(m->pos()).c_str());
405
        idb++;
406
    }
407
}
408

409
#include <Mod/TechDraw/Gui/moc_QGEPath.cpp>
410

411

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.