src/editmodes/drawmode.cc

changeset 830
a741a0b9df49
parent 829
bb903e89e23c
child 831
3cd913bf0c48
equal deleted inserted replaced
829:bb903e89e23c 830:a741a0b9df49
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013, 2014 Santeri Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <QPainter>
20 #include <QMouseEvent>
21 #include "drawmode.h"
22 #include "../ldObject.h"
23 #include "../glRenderer.h"
24
25 CFGENTRY (Bool, drawLineLengths, true)
26 CFGENTRY (Bool, drawAngles, false)
27
28 DrawMode::DrawMode (GLRenderer* renderer) :
29 Super (renderer),
30 _rectdraw (false) {}
31
32 EditModeType DrawMode::type() const
33 {
34 return EditModeType::Draw;
35 }
36
37 void DrawMode::render (QPainter& painter) const
38 {
39 QPoint poly[4];
40 Vertex poly3d[4];
41 int numverts = 4;
42 QFontMetrics metrics = QFontMetrics (QFont());
43
44 // Calculate polygon data
45 if (not _rectdraw)
46 {
47 numverts = _drawedVerts.size() + 1;
48 int i = 0;
49
50 for (Vertex const& vert : _drawedVerts)
51 poly3d[i++] = vert;
52
53 // Draw the cursor vertex as the last one in the list.
54 if (numverts <= 4)
55 poly3d[i] = renderer()->position3D();
56 else
57 numverts = 4;
58 }
59 else
60 {
61 // Get vertex information from m_rectverts
62 if (_drawedVerts.size() > 0)
63 for (int i = 0; i < numverts; ++i)
64 poly3d[i] = _rectverts[i];
65 else
66 poly3d[0] = renderer()->position3D();
67 }
68
69 // Convert to 2D
70 for (int i = 0; i < numverts; ++i)
71 poly[i] = renderer()->coordconv3_2 (poly3d[i]);
72
73 if (numverts > 0)
74 {
75 // Draw the polygon-to-be
76 painter.setBrush (_polybrush);
77 painter.drawPolygon (poly, numverts);
78
79 // Draw vertex blips
80 for (int i = 0; i < numverts; ++i)
81 {
82 QPoint& blip = poly[i];
83 painter.setPen (renderer()->linePen());
84 renderer()->drawBlip (painter, blip);
85
86 // Draw their coordinates
87 painter.setPen (renderer()->textPen());
88 painter.drawText (blip.x(), blip.y() - 8, poly3d[i].toString (true));
89 }
90
91 // Draw line lenghts and angle info if appropriate
92 if (numverts >= 2)
93 {
94 int numlines = (_drawedVerts.size() == 1) ? 1 : _drawedVerts.size() + 1;
95 painter.setPen (renderer()->textPen());
96
97 for (int i = 0; i < numlines; ++i)
98 {
99 const int j = (i + 1 < numverts) ? i + 1 : 0;
100 const int h = (i - 1 >= 0) ? i - 1 : numverts - 1;
101
102 if (cfg::drawLineLengths)
103 {
104 const QString label = QString::number ((poly3d[j] - poly3d[i]).length());
105 QPoint origin = QLineF (poly[i], poly[j]).pointAt (0.5).toPoint();
106 painter.drawText (origin, label);
107 }
108
109 if (cfg::drawAngles)
110 {
111 QLineF l0 (poly[h], poly[i]),
112 l1 (poly[i], poly[j]);
113
114 double angle = 180 - l0.angleTo (l1);
115
116 if (angle < 0)
117 angle = 180 - l1.angleTo (l0);
118
119 QString label = QString::number (angle) + QString::fromUtf8 (QByteArray ("\302\260"));
120 QPoint pos = poly[i];
121 pos.setY (pos.y() + metrics.height());
122
123 painter.drawText (pos, label);
124 }
125 }
126 }
127 }
128 }
129
130 bool DrawMode::preAddVertex (Vertex const& pos)
131 {
132 // If we picked an already-existing vertex, stop drawing
133 for (Vertex& vert : _drawedVerts)
134 {
135 if (vert == pos)
136 {
137 endDraw();
138 return true;
139 }
140 }
141
142 return false;
143 }
144
145 bool DrawMode::mouseReleased (MouseEventData const& data)
146 {
147 if (Super::mouseReleased (data))
148 return true;
149
150 if (data.releasedButtons & Qt::LeftButton)
151 {
152 if (_rectdraw)
153 {
154 if (_drawedVerts.size() == 2)
155 {
156 endDraw();
157 return true;
158 }
159 }
160 else
161 {
162 // If we have 4 verts, stop drawing.
163 if (_drawedVerts.size() >= 4)
164 {
165 endDraw();
166 return true;
167 }
168
169 if (_drawedVerts.isEmpty())
170 {
171 _rectdraw = (data.ev->modifiers() & Qt::ShiftModifier);
172 updateRectVerts();
173 }
174 }
175
176 addDrawnVertex (renderer()->position3D());
177 return true;
178 }
179
180 return false;
181 }
182
183 //
184 // Update rect vertices when the mouse moves since the 3d position likely has changed
185 //
186 bool DrawMode::mouseMoved (QMouseEvent*)
187 {
188 updateRectVerts();
189 return false;
190 }
191
192 void DrawMode::updateRectVerts()
193 {
194 if (not _rectdraw)
195 return;
196
197 if (_drawedVerts.isEmpty())
198 {
199 for (int i = 0; i < 4; ++i)
200 _rectverts[i] = renderer()->position3D();
201
202 return;
203 }
204
205 Vertex v0 = _drawedVerts[0],
206 v1 = (_drawedVerts.size() >= 2) ? _drawedVerts[1] : renderer()->position3D();
207
208 const Axis localx = renderer()->getCameraAxis (false),
209 localy = renderer()->getCameraAxis (true),
210 localz = (Axis) (3 - localx - localy);
211
212 for (int i = 0; i < 4; ++i)
213 _rectverts[i].setCoordinate (localz, renderer()->getDepthValue());
214
215 _rectverts[0].setCoordinate (localx, v0[localx]);
216 _rectverts[0].setCoordinate (localy, v0[localy]);
217 _rectverts[1].setCoordinate (localx, v1[localx]);
218 _rectverts[1].setCoordinate (localy, v0[localy]);
219 _rectverts[2].setCoordinate (localx, v1[localx]);
220 _rectverts[2].setCoordinate (localy, v1[localy]);
221 _rectverts[3].setCoordinate (localx, v0[localx]);
222 _rectverts[3].setCoordinate (localy, v1[localy]);
223 }
224
225 void DrawMode::endDraw()
226 {
227 // Clean the selection and create the object
228 QList<Vertex>& verts = _drawedVerts;
229 LDObjectList objs;
230
231 if (_rectdraw)
232 {
233 LDQuadPtr quad (spawn<LDQuad>());
234
235 updateRectVerts();
236
237 for (int i = 0; i < quad->numVertices(); ++i)
238 quad->setVertex (i, _rectverts[i]);
239
240 quad->setColor (maincolor());
241 objs << quad;
242 }
243 else
244 {
245 switch (verts.size())
246 {
247 case 1:
248 {
249 // 1 vertex - add a vertex object
250 LDVertexPtr obj = spawn<LDVertex>();
251 obj->pos = verts[0];
252 obj->setColor (maincolor());
253 objs << obj;
254 break;
255 }
256
257 case 2:
258 {
259 // 2 verts - make a line
260 LDLinePtr obj = spawn<LDLine> (verts[0], verts[1]);
261 obj->setColor (edgecolor());
262 objs << obj;
263 break;
264 }
265
266 case 3:
267 case 4:
268 {
269 LDObjectPtr obj = (verts.size() == 3) ?
270 static_cast<LDObjectPtr> (spawn<LDTriangle>()) :
271 static_cast<LDObjectPtr> (spawn<LDQuad>());
272
273 obj->setColor (maincolor());
274
275 for (int i = 0; i < verts.size(); ++i)
276 obj->setVertex (i, verts[i]);
277
278 objs << obj;
279 break;
280 }
281 }
282 }
283
284 finishDraw (objs);
285 _rectdraw = false;
286 }

mercurial