FreeCAD

Форк
0
/
QGIArrow.cpp 
340 строк · 11.2 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2013 Luke Parry <l.parry@warwick.ac.uk>                 *
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 <cassert>
26
# include <QPainterPath>
27
#endif
28

29
#include <Mod/TechDraw/App/ArrowPropEnum.h>
30

31
#include "QGIArrow.h"
32
#include "PreferencesGui.h"
33
#include "Rez.h"
34

35

36
using namespace TechDrawGui;
37
using namespace TechDraw;
38

39
QGIArrow::QGIArrow() :
40
    m_fill(Qt::SolidPattern),
41
    m_size(getPrefArrowSize()),
42
    m_style(0),
43
    m_dirMode(false),
44
    m_dir(Base::Vector3d(1.0, 0.0, 0.0))
45
{
46
    setFlipped(false);
47
    setFillStyle(Qt::SolidPattern);
48
    m_brush.setStyle(m_fill);
49
    m_colDefFill = getNormalColor();
50
    m_colNormalFill = m_colDefFill;
51

52
    setCacheMode(QGraphicsItem::NoCache);
53
    setAcceptHoverEvents(false);
54
    setFlag(QGraphicsItem::ItemIsSelectable, false);
55
    setFlag(QGraphicsItem::ItemIsMovable, false);
56
}
57

58
void QGIArrow::draw() {
59
    QPainterPath path;
60
    if (m_style == ArrowType::FILLED_ARROW) {
61
        if (m_dirMode) {
62
            path = makeFilledTriangle(getDirection(), m_size, m_size/6.0);
63
        } else {
64
            path = makeFilledTriangle(m_size, m_size/6.0, isFlipped());     //"arrow l/w sb 3/1" ??
65
        }
66
    } else if (m_style == ArrowType::OPEN_ARROW) {
67
        if (m_dirMode) {
68
            path = makeOpenArrow(getDirection(), m_size, m_size/3.0);          //broad arrow?
69
        } else {
70
            path = makeOpenArrow(m_size, m_size/3.0, isFlipped());
71
        }
72
    } else if (m_style == ArrowType::TICK) {
73
        if (m_dirMode) {
74
            path = makeHashMark(getDirection(), m_size/2.0, m_size/2.0);       //big enough?
75
        } else {
76
            path = makeHashMark(m_size/2.0, m_size/2.0, isFlipped());       //big enough?
77
        }
78
    } else if (m_style == ArrowType::DOT) {
79
        path = makeDot(m_size/2.0, m_size/2.0, isFlipped());
80
    } else if (m_style == ArrowType::OPEN_CIRCLE) {
81
        path = makeOpenDot(m_size/2.0, m_size/2.0, isFlipped());
82
    } else if (m_style == ArrowType::FORK) {
83
        if (m_dirMode) {
84
            path = makeForkArrow(getDirection(), m_size/2.0, m_size/2.0);       //big enough?
85
        } else {
86
            path = makeForkArrow(m_size/2.0, m_size/2.0, isFlipped());       //big enough?
87
        }
88
    } else if (m_style == ArrowType::FILLED_TRIANGLE){
89
        if (m_dirMode) {
90
            path = makePyramid(getDirection(), m_size);
91
        } else {
92
            path = makePyramid(m_size, isFlipped());
93
        }
94
    }else {
95
        path = makeFilledTriangle(m_size, m_size/6.0, isFlipped());     //sb a question mark or ???
96
    }
97
    setPath(path);
98
}
99

100
void QGIArrow::setSize(double s)
101
{
102
    m_size = s;
103
}
104

105

106
QPainterPath QGIArrow::makeFilledTriangle(double length, double width, bool flipped)
107
{
108
//(0, 0) is tip of arrow
109
    if (!flipped) {
110
        length *= -1;
111
    }
112

113
    QPainterPath path;
114
    path.moveTo(QPointF(0., 0.));
115
    path.lineTo(QPointF(Rez::guiX(length), Rez::guiX(-width)));
116
    path.lineTo(QPointF(Rez::guiX(length), Rez::guiX(width)));
117
    path.closeSubpath();
118
    setFillStyle(Qt::SolidPattern);
119
    return path;
120
}
121

122
QPainterPath QGIArrow::makeFilledTriangle(Base::Vector3d dir, double length, double width)
123
{
124
//(0, 0) is tip of arrow
125
// dir is direction arrow points
126
    Base::Vector3d negDir = -dir;
127
    negDir.Normalize();
128
    Base::Vector3d perp(-negDir.y, negDir.x, 0.0);
129
    Base::Vector3d barb1 = negDir * length + perp * width;
130
    Base::Vector3d barb2 = negDir * length - perp * width;
131

132
    QPainterPath path;
133
    path.moveTo(QPointF(0., 0.));
134
    path.lineTo(QPointF(Rez::guiX(barb1.x), Rez::guiX(barb1.y)));
135
    path.lineTo(QPointF(Rez::guiX(barb2.x), Rez::guiX(barb2.y)));
136
    path.closeSubpath();
137
    setFillStyle(Qt::SolidPattern);
138
    return path;
139
}
140

141
QPainterPath QGIArrow::makeOpenArrow(double length, double width, bool flipped)
142
{
143
//(0, 0) is tip of arrow
144
    if (!flipped) {
145
        length *= -1;
146
    }
147

148
    QPainterPath path;
149
    path.moveTo(QPointF(Rez::guiX(length), Rez::guiX(-width)));
150
    path.lineTo(QPointF(0., 0.));
151
    path.lineTo(QPointF(Rez::guiX(length), Rez::guiX(width)));
152
    setFillStyle(Qt::NoBrush);
153
    return path;
154
}
155

156
QPainterPath QGIArrow::makeOpenArrow(Base::Vector3d dir, double length, double width)
157
{
158
//(0, 0) is tip of arrow
159
    Base::Vector3d negDir = -dir;
160
    negDir.Normalize();
161
    Base::Vector3d perp(-negDir.y, negDir.x, 0.0);
162
    Base::Vector3d barb1 = negDir * length + perp * width;
163
    Base::Vector3d barb2 = negDir * length - perp * width;
164

165
    QPainterPath path;
166
    path.moveTo(QPointF(Rez::guiX(barb1.x), Rez::guiX(barb1.y)));
167
    path.lineTo(QPointF(0., 0.));
168
    path.lineTo(QPointF(Rez::guiX(barb2.x), Rez::guiX(barb2.y)));
169
    setFillStyle(Qt::NoBrush);
170
    return path;
171
}
172

173

174
QPainterPath QGIArrow::makeHashMark(double length, double width, bool flipped)   //Arch tick
175
{
176
    double adjWidth = 1.0;
177
//(0, 0) is tip of arrow
178
    if (!flipped) {
179
        length *= -1;
180
        adjWidth *= -1;
181
    }
182
    QPainterPath path;
183
    path.moveTo(QPointF(Rez::guiX(length), Rez::guiX(adjWidth * (-width))));
184
    path.lineTo(QPointF(Rez::guiX(-length), Rez::guiX(adjWidth * width)));
185
    setFillStyle(Qt::NoBrush);
186
    return path;
187
}
188

189
QPainterPath QGIArrow::makeHashMark(Base::Vector3d dir, double length, double width)   //Arch tick
190
{
191
    double adjWidth = 1.0;
192
    Base::Vector3d negDir = -dir;
193
    Base::Vector3d normDir = dir;
194
    negDir.Normalize();
195
    normDir.Normalize();
196
    Base::Vector3d perp(-negDir.y, negDir.x, 0.0);
197
    Base::Vector3d barb1 = negDir * length - perp * (adjWidth * width);
198
    Base::Vector3d barb2 = normDir * length + perp * (adjWidth * width);
199

200
    QPainterPath path;
201
    path.moveTo(QPointF(Rez::guiX(barb1.x), Rez::guiX(barb1.y)));
202
    path.lineTo(QPointF(Rez::guiX(barb2.x), Rez::guiX(barb2.y)));
203
    setFillStyle(Qt::NoBrush);
204
    return path;
205
}
206

207
QPainterPath QGIArrow::makeDot(double length, double width, bool flipped)   //closed dot
208
{
209
    Q_UNUSED(flipped);
210
    QPainterPath path;
211
    path.moveTo(0.0, 0.0);                                  ////(0, 0) is Center of dot
212
    path.addEllipse(Rez::guiX(-length/2.0), Rez::guiX(-width/2.0), Rez::guiX(length), Rez::guiX(width));
213
    setFillStyle(Qt::SolidPattern);
214
    return path;
215
}
216

217
QPainterPath QGIArrow::makeOpenDot(double length, double width, bool flipped)
218
{
219
    Q_UNUSED(flipped);
220
    QPainterPath path;
221
    path.moveTo(0.0, 0.0);                                  ////(0, 0) is Center of dot
222
    path.addEllipse(Rez::guiX(-length/2.0), Rez::guiX(-width/2.0), Rez::guiX(length), Rez::guiX(width));
223
    setFillStyle(Qt::NoBrush);
224
    return path;
225
}
226

227
QPainterPath QGIArrow::makeForkArrow(double length, double width, bool flipped)
228
{
229
//(0, 0) is tip of arrow
230
    if (flipped) {
231
        length *= -1;
232
    }
233

234
    QPainterPath path;
235
    path.moveTo(QPointF(Rez::guiX(length), Rez::guiX(-width)));
236
    path.lineTo(QPointF(0., 0.));
237
    path.lineTo(QPointF(Rez::guiX(length), Rez::guiX(width)));
238
    setFillStyle(Qt::NoBrush);
239
    return path;
240
}
241

242
QPainterPath QGIArrow::makeForkArrow(Base::Vector3d dir, double length, double width)
243
{
244
//(0, 0) is tip of arrow
245
    Base::Vector3d negDir = -dir;
246
    Base::Vector3d normDir = dir;
247
    negDir.Normalize();
248
    normDir.Normalize();
249
    Base::Vector3d perp(-normDir.y, normDir.x, 0.0);
250
    Base::Vector3d barb1 = normDir * length + perp * width;
251
    Base::Vector3d barb2 = normDir * length - perp * width;
252

253
    QPainterPath path;
254
    path.moveTo(QPointF(Rez::guiX(barb1.x), Rez::guiX(barb1.y)));
255
    path.lineTo(QPointF(0., 0.));
256
    path.lineTo(QPointF(Rez::guiX(barb2.x), Rez::guiX(barb2.y)));
257
    setFillStyle(Qt::NoBrush);
258
    return path;
259
}
260

261
QPainterPath QGIArrow::makePyramid(double length, bool flipped)
262
{
263
    double half_width = length/2.;
264
    double top = -length;
265
    double base = 0.;
266
    // [(0, -width), (0, width)] is base of arrow
267
    if (flipped) {
268
        top = 0.;
269
        base = -length;
270
    }
271
    top = Rez::guiX(top);
272
    base = Rez::guiX(base);
273
    QPainterPath path;
274
    path.moveTo(QPointF(top, 0.));
275
    path.lineTo(QPointF(base, Rez::guiX(-half_width)));
276
    path.lineTo(QPointF(base, Rez::guiX(half_width)));
277
    path.closeSubpath();
278
    setFillStyle(Qt::SolidPattern);
279
    return path;
280
}
281

282
QPainterPath QGIArrow::makePyramid(Base::Vector3d dir, double length)
283
{
284
    //(0, 0) is tip of arrow
285
    // dir is direction arrow points
286
    Base::Vector3d negDir = -dir;
287
    negDir.Normalize();
288
    double width = length / 2.;
289
    Base::Vector3d perp(-negDir.y, negDir.x, 0.0);
290
    Base::Vector3d barb1 = perp * width;
291
    Base::Vector3d barb2 = perp * -width;
292
    Base::Vector3d top = negDir * length;
293

294
    QPainterPath path;
295
    path.moveTo(QPointF(Rez::guiX(top.x), Rez::guiX(top.y)));
296
    path.lineTo(QPointF(Rez::guiX(barb1.x), Rez::guiX(barb1.y)));
297
    path.lineTo(QPointF(Rez::guiX(barb2.x), Rez::guiX(barb2.y)));
298
    path.closeSubpath();
299
    setFillStyle(Qt::SolidPattern);
300
    return path;
301
}
302

303
int QGIArrow::getPrefArrowStyle()
304
{
305
    return PreferencesGui::dimArrowStyle();
306
}
307

308
double QGIArrow::getPrefArrowSize()
309
{
310
    return PreferencesGui::dimArrowSize();
311
}
312

313
double QGIArrow::getOverlapAdjust(int style, double size)
314
{
315
    // adjustment required depends on arrow size and type! :(
316
    // ex for fork and tick, adjustment sb zero. 0.25 is good for filled triangle, 0.1 for open arrow.
317
    // open circle sb = radius
318
    // NOTE: this may need to be adjusted to account for line thickness too.
319
//    Base::Console().Message("QGIA::getOverlapAdjust(%d, %.3f) \n", style, size);
320
    switch(style) {
321
        case FILLED_ARROW:
322
            return 0.50 * size;
323
        case OPEN_ARROW:
324
            return 0.10 * size;
325
        case TICK:
326
            return 0.0;
327
        case DOT:
328
            return 0.0;
329
        case OPEN_CIRCLE:
330
                        //diameter is size/2 so radius is size/4
331
            return 0.25 * size;
332
        case FORK:
333
            return 0.0;
334
        case FILLED_TRIANGLE:
335
            return size;
336
        case NONE:
337
            return 0.0;
338
    }
339
    return 1.0;  // Unknown
340
}
341

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

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

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

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