23 #include "gui.h" |
23 #include "gui.h" |
24 #include "history.h" |
24 #include "history.h" |
25 #include "gldraw.h" |
25 #include "gldraw.h" |
26 #include "colors.h" |
26 #include "colors.h" |
27 |
27 |
28 cfg( String, ld_defaultname, ""); |
28 cfg (String, ld_defaultname, ""); |
29 cfg( String, ld_defaultuser, ""); |
29 cfg (String, ld_defaultuser, ""); |
30 cfg( Int, ld_defaultlicense, 0); |
30 cfg (Int, ld_defaultlicense, 0); |
31 |
31 |
32 // List of all LDObjects |
32 // List of all LDObjects |
33 static QList<LDObject*> g_LDObjects; |
33 static QList<LDObject*> g_LDObjects; |
34 |
34 |
35 // ============================================================================= |
35 // ============================================================================= |
36 // LDObject constructors |
36 // LDObject constructors |
37 // ----------------------------------------------------------------------------- |
37 // ----------------------------------------------------------------------------- |
38 LDObject::LDObject() : |
38 LDObject::LDObject() : |
39 m_Hidden( false), |
39 m_Hidden (false), |
40 m_Selected( false), |
40 m_Selected (false), |
41 m_Parent( null), |
41 m_Parent (null), |
42 m_File( null), |
42 m_File (null), |
43 m_GLInit( false), |
43 m_GLInit (false), |
44 qObjListEntry( null) |
44 qObjListEntry (null) |
45 { |
45 { |
46 memset( m_coords, 0, sizeof m_coords); |
46 memset (m_coords, 0, sizeof m_coords); |
47 chooseID(); |
47 chooseID(); |
48 g_LDObjects << this; |
48 g_LDObjects << this; |
49 } |
49 } |
50 |
50 |
51 // ============================================================================= |
51 // ============================================================================= |
52 // ----------------------------------------------------------------------------- |
52 // ----------------------------------------------------------------------------- |
53 void LDObject::chooseID() |
53 void LDObject::chooseID() |
54 { |
54 { |
55 int32 id = 1; // 0 shalt be null |
55 int32 id = 1; // 0 shalt be null |
56 |
56 |
57 for( LDObject* obj : g_LDObjects) |
57 for (LDObject* obj : g_LDObjects) |
58 { |
58 { |
59 assert( obj != this); |
59 assert (obj != this); |
60 |
60 |
61 if( obj->getID() >= id) |
61 if (obj->getID() >= id) |
62 id = obj->getID() + 1; |
62 id = obj->getID() + 1; |
63 } |
63 } |
64 |
64 |
65 setID( id); |
65 setID (id); |
66 } |
66 } |
67 |
67 |
68 // ============================================================================= |
68 // ============================================================================= |
69 // Default implementations for LDObject's virtual methods. These should never be |
69 // Default implementations for LDObject's virtual methods. These should never be |
70 // actually called, for a subclass-less LDObject should never come into existance. |
70 // actually called, for a subclass-less LDObject should never come into existance. |
71 // These exist only to satisfy the linker. |
71 // These exist only to satisfy the linker. |
72 // ----------------------------------------------------------------------------- |
72 // ----------------------------------------------------------------------------- |
73 LDObject::Type LDObject::getType() const |
73 LDObject::Type LDObject::getType() const |
74 { |
74 { |
75 return LDObject::Unidentified; |
75 return LDObject::EUnidentified; |
76 } |
76 } |
77 |
77 |
78 bool LDObject::hasMatrix() const |
78 bool LDObject::hasMatrix() const |
79 { |
79 { |
80 return false; |
80 return false; |
100 return 0; |
100 return 0; |
101 } |
101 } |
102 |
102 |
103 // ============================================================================= |
103 // ============================================================================= |
104 // ----------------------------------------------------------------------------- |
104 // ----------------------------------------------------------------------------- |
105 void LDObject::setVertexCoord( int i, Axis ax, double value) |
105 void LDObject::setVertexCoord (int i, Axis ax, double value) |
106 { |
106 { |
107 vertex v = getVertex( i); |
107 Vertex v = getVertex (i); |
108 v[ax] = value; |
108 v[ax] = value; |
109 setVertex( i, v); |
109 setVertex (i, v); |
110 } |
110 } |
111 |
111 |
112 LDError::LDError() {} |
112 LDError::LDError() {} |
113 |
113 |
114 // ============================================================================= |
114 // ============================================================================= |
115 // ----------------------------------------------------------------------------- |
115 // ----------------------------------------------------------------------------- |
116 str LDComment::raw() const |
116 str LDComment::raw() const |
117 { |
117 { |
118 return fmt( "0 %1", text); |
118 return fmt ("0 %1", text); |
119 } |
119 } |
120 |
120 |
121 // ============================================================================= |
121 // ============================================================================= |
122 // ----------------------------------------------------------------------------- |
122 // ----------------------------------------------------------------------------- |
123 str LDSubfile::raw() const |
123 str LDSubfile::raw() const |
124 { |
124 { |
125 str val = fmt( "1 %1 %2 ", getColor(), getPosition()); |
125 str val = fmt ("1 %1 %2 ", getColor(), getPosition()); |
126 val += getTransform().stringRep(); |
126 val += getTransform().stringRep(); |
127 val += ' '; |
127 val += ' '; |
128 val += getFileInfo()->getName(); |
128 val += getFileInfo()->getName(); |
129 return val; |
129 return val; |
130 } |
130 } |
131 |
131 |
132 // ============================================================================= |
132 // ============================================================================= |
133 // ----------------------------------------------------------------------------- |
133 // ----------------------------------------------------------------------------- |
134 str LDLine::raw() const |
134 str LDLine::raw() const |
135 { |
135 { |
136 str val = fmt( "2 %1", getColor()); |
136 str val = fmt ("2 %1", getColor()); |
137 |
137 |
138 for( int i = 0; i < 2; ++i) |
138 for (int i = 0; i < 2; ++i) |
139 val += fmt( " %1", getVertex( i)); |
139 val += fmt (" %1", getVertex (i)); |
140 |
140 |
141 return val; |
141 return val; |
142 } |
142 } |
143 |
143 |
144 // ============================================================================= |
144 // ============================================================================= |
145 // ----------------------------------------------------------------------------- |
145 // ----------------------------------------------------------------------------- |
146 str LDTriangle::raw() const |
146 str LDTriangle::raw() const |
147 { |
147 { |
148 str val = fmt( "3 %1", getColor()); |
148 str val = fmt ("3 %1", getColor()); |
149 |
149 |
150 for( int i = 0; i < 3; ++i) |
150 for (int i = 0; i < 3; ++i) |
151 val += fmt( " %1", getVertex( i)); |
151 val += fmt (" %1", getVertex (i)); |
152 |
152 |
153 return val; |
153 return val; |
154 } |
154 } |
155 |
155 |
156 // ============================================================================= |
156 // ============================================================================= |
157 // ----------------------------------------------------------------------------- |
157 // ----------------------------------------------------------------------------- |
158 str LDQuad::raw() const |
158 str LDQuad::raw() const |
159 { |
159 { |
160 str val = fmt( "4 %1", getColor()); |
160 str val = fmt ("4 %1", getColor()); |
161 |
161 |
162 for( int i = 0; i < 4; ++i) |
162 for (int i = 0; i < 4; ++i) |
163 val += fmt( " %1", getVertex( i)); |
163 val += fmt (" %1", getVertex (i)); |
164 |
164 |
165 return val; |
165 return val; |
166 } |
166 } |
167 |
167 |
168 // ============================================================================= |
168 // ============================================================================= |
169 // ----------------------------------------------------------------------------- |
169 // ----------------------------------------------------------------------------- |
170 str LDCondLine::raw() const |
170 str LDCondLine::raw() const |
171 { |
171 { |
172 str val = fmt( "5 %1", getColor()); |
172 str val = fmt ("5 %1", getColor()); |
173 |
173 |
174 // Add the coordinates |
174 // Add the coordinates |
175 for( int i = 0; i < 4; ++i) |
175 for (int i = 0; i < 4; ++i) |
176 val += fmt( " %1", getVertex( i)); |
176 val += fmt (" %1", getVertex (i)); |
177 |
177 |
178 return val; |
178 return val; |
179 } |
179 } |
180 |
180 |
181 // ============================================================================= |
181 // ============================================================================= |
228 // 0---3 0---3 3 |
228 // 0---3 0---3 3 |
229 // | | | / /| |
229 // | | | / /| |
230 // | | ==> | / / | |
230 // | | ==> | / / | |
231 // | | |/ / | |
231 // | | |/ / | |
232 // 1---2 1 1---2 |
232 // 1---2 1 1---2 |
233 LDTriangle* tri1 = new LDTriangle( getVertex( 0), getVertex( 1), getVertex( 3)); |
233 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
234 LDTriangle* tri2 = new LDTriangle( getVertex( 1), getVertex( 2), getVertex( 3)); |
234 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
235 |
235 |
236 // The triangles also inherit the quad's color |
236 // The triangles also inherit the quad's color |
237 tri1->setColor( getColor()); |
237 tri1->setColor (getColor()); |
238 tri2->setColor( getColor()); |
238 tri2->setColor (getColor()); |
239 |
239 |
240 QList<LDTriangle*> triangles; |
240 QList<LDTriangle*> triangles; |
241 triangles << tri1; |
241 triangles << tri1; |
242 triangles << tri2; |
242 triangles << tri2; |
243 return triangles; |
243 return triangles; |
244 } |
244 } |
245 |
245 |
246 // ============================================================================= |
246 // ============================================================================= |
247 // ----------------------------------------------------------------------------- |
247 // ----------------------------------------------------------------------------- |
248 void LDObject::replace( LDObject* other) |
248 void LDObject::replace (LDObject* other) |
249 { |
249 { |
250 long idx = getIndex(); |
250 long idx = getIndex(); |
251 assert( idx != -1); |
251 assert (idx != -1); |
252 |
252 |
253 // Replace the instance of the old object with the new object |
253 // Replace the instance of the old object with the new object |
254 getFile()->setObject( idx, other); |
254 getFile()->setObject (idx, other); |
255 |
255 |
256 // Remove the old object |
256 // Remove the old object |
257 deleteSelf(); |
257 deleteSelf(); |
258 } |
258 } |
259 |
259 |
260 // ============================================================================= |
260 // ============================================================================= |
261 // ----------------------------------------------------------------------------- |
261 // ----------------------------------------------------------------------------- |
262 void LDObject::swap( LDObject* other) |
262 void LDObject::swap (LDObject* other) |
263 { |
263 { |
264 assert( getFile() == other->getFile()); |
264 assert (getFile() == other->getFile()); |
265 getFile()->swapObjects( this, other); |
265 getFile()->swapObjects (this, other); |
266 } |
266 } |
267 |
267 |
268 // ============================================================================= |
268 // ============================================================================= |
269 // ----------------------------------------------------------------------------- |
269 // ----------------------------------------------------------------------------- |
270 LDLine::LDLine( vertex v1, vertex v2) |
270 LDLine::LDLine (Vertex v1, Vertex v2) |
271 { |
271 { |
272 setVertex( 0, v1); |
272 setVertex (0, v1); |
273 setVertex( 1, v2); |
273 setVertex (1, v2); |
274 } |
274 } |
275 |
275 |
276 // ============================================================================= |
276 // ============================================================================= |
277 // ----------------------------------------------------------------------------- |
277 // ----------------------------------------------------------------------------- |
278 LDQuad::LDQuad( const vertex& v0, const vertex& v1, const vertex& v2, const vertex& v3) |
278 LDQuad::LDQuad (const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3) |
279 { |
279 { |
280 setVertex( 0, v0); |
280 setVertex (0, v0); |
281 setVertex( 1, v1); |
281 setVertex (1, v1); |
282 setVertex( 2, v2); |
282 setVertex (2, v2); |
283 setVertex( 3, v3); |
283 setVertex (3, v3); |
284 } |
284 } |
285 |
285 |
286 // ============================================================================= |
286 // ============================================================================= |
287 // ----------------------------------------------------------------------------- |
287 // ----------------------------------------------------------------------------- |
288 LDObject::~LDObject() {} |
288 LDObject::~LDObject() {} |
294 // ============================================================================= |
294 // ============================================================================= |
295 // ----------------------------------------------------------------------------- |
295 // ----------------------------------------------------------------------------- |
296 void LDObject::deleteSelf() |
296 void LDObject::deleteSelf() |
297 { |
297 { |
298 // If this object was selected, unselect it now |
298 // If this object was selected, unselect it now |
299 if( isSelected()) |
299 if (isSelected()) |
300 unselect(); |
300 unselect(); |
301 |
301 |
302 // If this object was associated to a file, remove it off it now |
302 // If this object was associated to a file, remove it off it now |
303 if( getFile()) |
303 if (getFile()) |
304 getFile()->forgetObject( this); |
304 getFile()->forgetObject (this); |
305 |
305 |
306 // Delete the GL lists |
306 // Delete the GL lists |
307 GL::deleteLists( this); |
307 GL::deleteLists (this); |
308 |
308 |
309 // Remove this object from the list of LDObjects |
309 // Remove this object from the list of LDObjects |
310 g_LDObjects.removeOne( this); |
310 g_LDObjects.removeOne (this); |
311 |
311 |
312 delete this; |
312 delete this; |
313 } |
313 } |
314 |
314 |
315 // ============================================================================= |
315 // ============================================================================= |
316 // ----------------------------------------------------------------------------- |
316 // ----------------------------------------------------------------------------- |
317 static void transformObject( LDObject* obj, matrix transform, vertex pos, int parentcolor) |
317 static void transformObject (LDObject* obj, Matrix transform, Vertex pos, int parentcolor) |
318 { |
318 { |
319 switch( obj->getType()) |
319 switch (obj->getType()) |
320 { |
320 { |
321 case LDObject::Line: |
321 case LDObject::ELine: |
322 case LDObject::CondLine: |
322 case LDObject::ECondLine: |
323 case LDObject::Triangle: |
323 case LDObject::ETriangle: |
324 case LDObject::Quad: |
324 case LDObject::EQuad: |
325 |
325 |
326 for( int i = 0; i < obj->vertices(); ++i) |
326 for (int i = 0; i < obj->vertices(); ++i) |
327 { |
327 { |
328 vertex v = obj->getVertex( i); |
328 Vertex v = obj->getVertex (i); |
329 v.transform( transform, pos); |
329 v.transform (transform, pos); |
330 obj->setVertex( i, v); |
330 obj->setVertex (i, v); |
331 } |
331 } |
332 |
332 |
333 break; |
333 break; |
334 |
334 |
335 case LDObject::Subfile: |
335 case LDObject::ESubfile: |
336 { |
336 { |
337 LDSubfile* ref = static_cast<LDSubfile*>( obj); |
337 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
338 matrix newMatrix = transform * ref->getTransform(); |
338 Matrix newMatrix = transform * ref->getTransform(); |
339 vertex newpos = ref->getPosition(); |
339 Vertex newpos = ref->getPosition(); |
340 |
340 |
341 newpos.transform( transform, pos); |
341 newpos.transform (transform, pos); |
342 ref->setPosition( newpos); |
342 ref->setPosition (newpos); |
343 ref->setTransform( newMatrix); |
343 ref->setTransform (newMatrix); |
344 } |
344 } |
345 break; |
345 break; |
346 |
346 |
347 default: |
347 default: |
348 break; |
348 break; |
349 } |
349 } |
350 |
350 |
351 if( obj->getColor() == maincolor) |
351 if (obj->getColor() == maincolor) |
352 obj->setColor( parentcolor); |
352 obj->setColor (parentcolor); |
353 } |
353 } |
354 |
354 |
355 // ============================================================================= |
355 // ============================================================================= |
356 // ----------------------------------------------------------------------------- |
356 // ----------------------------------------------------------------------------- |
357 QList<LDObject*> LDSubfile::inlineContents( InlineFlags flags) |
357 QList<LDObject*> LDSubfile::inlineContents (InlineFlags flags) |
358 { |
358 { |
359 QList<LDObject*> objs = getFileInfo()->inlineContents( flags); |
359 QList<LDObject*> objs = getFileInfo()->inlineContents (flags); |
360 |
360 |
361 // Transform the objects |
361 // Transform the objects |
362 for( LDObject* obj : objs) |
362 for (LDObject* obj : objs) |
363 { |
363 { |
364 // Set the parent now so we know what inlined the object. |
364 // Set the parent now so we know what inlined the object. |
365 obj->setParent( this); |
365 obj->setParent (this); |
366 transformObject( obj, getTransform(), getPosition(), getColor()); |
366 transformObject (obj, getTransform(), getPosition(), getColor()); |
367 } |
367 } |
368 |
368 |
369 return objs; |
369 return objs; |
370 } |
370 } |
371 |
371 |
372 // ============================================================================= |
372 // ============================================================================= |
373 // ----------------------------------------------------------------------------- |
373 // ----------------------------------------------------------------------------- |
374 long LDObject::getIndex() const |
374 long LDObject::getIndex() const |
375 { |
375 { |
376 assert( getFile() != null); |
376 assert (getFile() != null); |
377 |
377 |
378 for( int i = 0; i < getFile()->getObjectCount(); ++i) |
378 for (int i = 0; i < getFile()->getObjectCount(); ++i) |
379 if( getFile()->getObject( i) == this) |
379 if (getFile()->getObject (i) == this) |
380 return i; |
380 return i; |
381 |
381 |
382 return -1; |
382 return -1; |
383 } |
383 } |
384 |
384 |
385 // ============================================================================= |
385 // ============================================================================= |
386 // ----------------------------------------------------------------------------- |
386 // ----------------------------------------------------------------------------- |
387 void LDObject::moveObjects( QList<LDObject*> objs, const bool up) |
387 void LDObject::moveObjects (QList<LDObject*> objs, const bool up) |
388 { |
388 { |
389 if( objs.isEmpty()) |
389 if (objs.isEmpty()) |
390 return; |
390 return; |
391 |
391 |
392 // If we move down, we need to iterate the array in reverse order. |
392 // If we move down, we need to iterate the array in reverse order. |
393 const long start = up ? 0 :( objs.size() - 1); |
393 const long start = up ? 0 : (objs.size() - 1); |
394 const long end = up ? objs.size() : -1; |
394 const long end = up ? objs.size() : -1; |
395 const long incr = up ? 1 : -1; |
395 const long incr = up ? 1 : -1; |
396 QList<LDObject*> objsToCompile; |
396 QList<LDObject*> objsToCompile; |
397 LDDocument* file = objs[0]->getFile(); |
397 LDDocument* file = objs[0]->getFile(); |
398 |
398 |
399 for( long i = start; i != end; i += incr) |
399 for (long i = start; i != end; i += incr) |
400 { |
400 { |
401 LDObject* obj = objs[i]; |
401 LDObject* obj = objs[i]; |
402 |
402 |
403 const long idx = obj->getIndex(), |
403 const long idx = obj->getIndex(), |
404 target = idx +( up ? -1 : 1); |
404 target = idx + (up ? -1 : 1); |
405 |
405 |
406 if( ( up && idx == 0) ||( !up && idx ==( long)( file->getObjects().size() - 1))) |
406 if ( (up && idx == 0) || (!up && idx == (long) (file->getObjects().size() - 1))) |
407 { |
407 { |
408 // One of the objects hit the extrema. If this happens, this should be the first |
408 // One of the objects hit the extrema. If this happens, this should be the first |
409 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
409 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
410 // abort the entire operation. |
410 // abort the entire operation. |
411 assert( i == start); |
411 assert (i == start); |
412 return; |
412 return; |
413 } |
413 } |
414 |
414 |
415 objsToCompile << obj; |
415 objsToCompile << obj; |
416 objsToCompile << file->getObject( target); |
416 objsToCompile << file->getObject (target); |
417 |
417 |
418 obj->swap( file->getObject( target)); |
418 obj->swap (file->getObject (target)); |
419 } |
419 } |
420 |
420 |
421 removeDuplicates( objsToCompile); |
421 removeDuplicates (objsToCompile); |
422 |
422 |
423 // The objects need to be recompiled, otherwise their pick lists are left with |
423 // The objects need to be recompiled, otherwise their pick lists are left with |
424 // the wrong index colors which messes up selection. |
424 // the wrong index colors which messes up selection. |
425 for( LDObject* obj : objsToCompile) |
425 for (LDObject* obj : objsToCompile) |
426 g_win->R()->compileObject( obj); |
426 g_win->R()->compileObject (obj); |
427 } |
427 } |
428 |
428 |
429 // ============================================================================= |
429 // ============================================================================= |
430 // ----------------------------------------------------------------------------- |
430 // ----------------------------------------------------------------------------- |
431 str LDObject::typeName( LDObject::Type type) |
431 str LDObject::typeName (LDObject::Type type) |
432 { |
432 { |
433 LDObject* obj = LDObject::getDefault( type); |
433 LDObject* obj = LDObject::getDefault (type); |
434 str name = obj->getTypeName(); |
434 str name = obj->getTypeName(); |
435 obj->deleteSelf(); |
435 obj->deleteSelf(); |
436 return name; |
436 return name; |
437 } |
437 } |
438 |
438 |
439 // ============================================================================= |
439 // ============================================================================= |
440 // ----------------------------------------------------------------------------- |
440 // ----------------------------------------------------------------------------- |
441 str LDObject::describeObjects( const QList<LDObject*>& objs) |
441 str LDObject::describeObjects (const QList<LDObject*>& objs) |
442 { |
442 { |
443 bool firstDetails = true; |
443 bool firstDetails = true; |
444 str text = ""; |
444 str text = ""; |
445 |
445 |
446 if( objs.isEmpty()) |
446 if (objs.isEmpty()) |
447 return "nothing"; // :) |
447 return "nothing"; // :) |
448 |
448 |
449 for( long i = 0; i < LDObject::NumTypes; ++i) |
449 for (long i = 0; i < ENumTypes; ++i) |
450 { |
450 { |
451 LDObject::Type objType =( LDObject::Type) i; |
451 Type objType = (Type) i; |
452 int count = 0; |
452 int count = 0; |
453 |
453 |
454 for( LDObject * obj : objs) |
454 for (LDObject * obj : objs) |
455 if( obj->getType() == objType) |
455 if (obj->getType() == objType) |
456 count++; |
456 count++; |
457 |
457 |
458 if( count == 0) |
458 if (count == 0) |
459 continue; |
459 continue; |
460 |
460 |
461 if( !firstDetails) |
461 if (!firstDetails) |
462 text += ", "; |
462 text += ", "; |
463 |
463 |
464 str noun = fmt( "%1%2", typeName( objType), plural( count)); |
464 str noun = fmt ("%1%2", typeName (objType), plural (count)); |
465 |
465 |
466 // Plural of "vertex" is "vertices", correct that |
466 // Plural of "vertex" is "vertices", correct that |
467 if( objType == LDObject::Vertex && count != 1) |
467 if (objType == EVertex && count != 1) |
468 noun = "vertices"; |
468 noun = "vertices"; |
469 |
469 |
470 text += fmt( "%1 %2", count, noun); |
470 text += fmt ("%1 %2", count, noun); |
471 firstDetails = false; |
471 firstDetails = false; |
472 } |
472 } |
473 |
473 |
474 return text; |
474 return text; |
475 } |
475 } |
476 |
476 |
477 // ============================================================================= |
477 // ============================================================================= |
478 // ----------------------------------------------------------------------------- |
478 // ----------------------------------------------------------------------------- |
479 LDObject* LDObject::topLevelParent() |
479 LDObject* LDObject::topLevelParent() |
480 { |
480 { |
481 if( !getParent()) |
481 if (!getParent()) |
482 return this; |
482 return this; |
483 |
483 |
484 LDObject* it = this; |
484 LDObject* it = this; |
485 |
485 |
486 while( it->getParent()) |
486 while (it->getParent()) |
487 it = it->getParent(); |
487 it = it->getParent(); |
488 |
488 |
489 return it; |
489 return it; |
490 } |
490 } |
491 |
491 |
492 // ============================================================================= |
492 // ============================================================================= |
493 // ----------------------------------------------------------------------------- |
493 // ----------------------------------------------------------------------------- |
494 LDObject* LDObject::next() const |
494 LDObject* LDObject::next() const |
495 { |
495 { |
496 long idx = getIndex(); |
496 long idx = getIndex(); |
497 assert( idx != -1); |
497 assert (idx != -1); |
498 |
498 |
499 if( idx ==( long) getFile()->getObjectCount() - 1) |
499 if (idx == (long) getFile()->getObjectCount() - 1) |
500 return null; |
500 return null; |
501 |
501 |
502 return getFile()->getObject( idx + 1); |
502 return getFile()->getObject (idx + 1); |
503 } |
503 } |
504 |
504 |
505 // ============================================================================= |
505 // ============================================================================= |
506 // ----------------------------------------------------------------------------- |
506 // ----------------------------------------------------------------------------- |
507 LDObject* LDObject::prev() const |
507 LDObject* LDObject::prev() const |
508 { |
508 { |
509 long idx = getIndex(); |
509 long idx = getIndex(); |
510 assert( idx != -1); |
510 assert (idx != -1); |
511 |
511 |
512 if( idx == 0) |
512 if (idx == 0) |
513 return null; |
513 return null; |
514 |
514 |
515 return getFile()->getObject( idx - 1); |
515 return getFile()->getObject (idx - 1); |
516 } |
516 } |
517 |
517 |
518 // ============================================================================= |
518 // ============================================================================= |
519 // ----------------------------------------------------------------------------- |
519 // ----------------------------------------------------------------------------- |
520 void LDObject::move( vertex vect) |
520 void LDObject::move (Vertex vect) |
521 { |
521 { |
522 if( hasMatrix()) |
522 if (hasMatrix()) |
523 { |
523 { |
524 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*>( this); |
524 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (this); |
525 mo->setPosition( mo->getPosition() + vect); |
525 mo->setPosition (mo->getPosition() + vect); |
526 } |
526 } |
527 elif( getType() == LDObject::Vertex) |
527 elif (getType() == LDObject::EVertex) |
528 { |
528 { |
529 // ugh |
529 // ugh |
530 static_cast<LDVertex*>( this)->pos += vect; |
530 static_cast<LDVertex*> (this)->pos += vect; |
531 } |
531 } |
532 else |
532 else |
533 { |
533 { |
534 for( int i = 0; i < vertices(); ++i) |
534 for (int i = 0; i < vertices(); ++i) |
535 setVertex( i, getVertex( i) + vect); |
535 setVertex (i, getVertex (i) + vect); |
536 } |
536 } |
537 } |
537 } |
538 |
538 |
539 // ============================================================================= |
539 // ============================================================================= |
540 // ----------------------------------------------------------------------------- |
540 // ----------------------------------------------------------------------------- |
541 #define CHECK_FOR_OBJ(N) \ |
541 #define CHECK_FOR_OBJ(N) \ |
542 if( type == LDObject::N) \ |
542 if (type == LDObject::E##N) \ |
543 return new LD##N; |
543 return new LD##N; |
544 |
544 |
545 LDObject* LDObject::getDefault( const LDObject::Type type) |
545 LDObject* LDObject::getDefault (const LDObject::Type type) |
546 { |
546 { |
547 CHECK_FOR_OBJ( Comment) |
547 CHECK_FOR_OBJ (Comment) |
548 CHECK_FOR_OBJ( BFC) |
548 CHECK_FOR_OBJ (BFC) |
549 CHECK_FOR_OBJ( Line) |
549 CHECK_FOR_OBJ (Line) |
550 CHECK_FOR_OBJ( CondLine) |
550 CHECK_FOR_OBJ (CondLine) |
551 CHECK_FOR_OBJ( Subfile) |
551 CHECK_FOR_OBJ (Subfile) |
552 CHECK_FOR_OBJ( Triangle) |
552 CHECK_FOR_OBJ (Triangle) |
553 CHECK_FOR_OBJ( Quad) |
553 CHECK_FOR_OBJ (Quad) |
554 CHECK_FOR_OBJ( Empty) |
554 CHECK_FOR_OBJ (Empty) |
555 CHECK_FOR_OBJ( BFC) |
555 CHECK_FOR_OBJ (BFC) |
556 CHECK_FOR_OBJ( Error) |
556 CHECK_FOR_OBJ (Error) |
557 CHECK_FOR_OBJ( Vertex) |
557 CHECK_FOR_OBJ (Vertex) |
558 CHECK_FOR_OBJ( Overlay) |
558 CHECK_FOR_OBJ (Overlay) |
559 return null; |
559 return null; |
560 } |
560 } |
561 |
561 |
562 // ============================================================================= |
562 // ============================================================================= |
563 // ----------------------------------------------------------------------------- |
563 // ----------------------------------------------------------------------------- |
602 // flipped but I don't have a method for checking flatness yet. |
602 // flipped but I don't have a method for checking flatness yet. |
603 // Food for thought... |
603 // Food for thought... |
604 |
604 |
605 int idx = getIndex(); |
605 int idx = getIndex(); |
606 |
606 |
607 if( idx > 0) |
607 if (idx > 0) |
608 { |
608 { |
609 LDBFC* bfc = dynamic_cast<LDBFC*>( prev()); |
609 LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); |
610 |
610 |
611 if( bfc && bfc->type == LDBFC::InvertNext) |
611 if (bfc && bfc->type == LDBFC::InvertNext) |
612 { |
612 { |
613 // This is prefixed with an invertnext, thus remove it. |
613 // This is prefixed with an invertnext, thus remove it. |
614 bfc->deleteSelf(); |
614 bfc->deleteSelf(); |
615 return; |
615 return; |
616 } |
616 } |
617 } |
617 } |
618 |
618 |
619 // Not inverted, thus prefix it with a new invertnext. |
619 // Not inverted, thus prefix it with a new invertnext. |
620 LDBFC* bfc = new LDBFC( LDBFC::InvertNext); |
620 LDBFC* bfc = new LDBFC (LDBFC::InvertNext); |
621 getFile()->insertObj( idx, bfc); |
621 getFile()->insertObj (idx, bfc); |
622 } |
622 } |
623 |
623 |
624 // ============================================================================= |
624 // ============================================================================= |
625 // ----------------------------------------------------------------------------- |
625 // ----------------------------------------------------------------------------- |
626 static void invertLine( LDObject* line) |
626 static void invertLine (LDObject* line) |
627 { |
627 { |
628 // For lines, we swap the vertices. I don't think that a |
628 // For lines, we swap the vertices. I don't think that a |
629 // cond-line's control points need to be swapped, do they? |
629 // cond-line's control points need to be swapped, do they? |
630 vertex tmp = line->getVertex( 0); |
630 Vertex tmp = line->getVertex (0); |
631 line->setVertex( 0, line->getVertex( 1)); |
631 line->setVertex (0, line->getVertex (1)); |
632 line->setVertex( 1, tmp); |
632 line->setVertex (1, tmp); |
633 } |
633 } |
634 |
634 |
635 void LDLine::invert() |
635 void LDLine::invert() |
636 { |
636 { |
637 invertLine( this); |
637 invertLine (this); |
638 } |
638 } |
639 |
639 |
640 void LDCondLine::invert() |
640 void LDCondLine::invert() |
641 { |
641 { |
642 invertLine( this); |
642 invertLine (this); |
643 } |
643 } |
644 |
644 |
645 void LDVertex::invert() {} |
645 void LDVertex::invert() {} |
646 |
646 |
647 // ============================================================================= |
647 // ============================================================================= |
648 // ----------------------------------------------------------------------------- |
648 // ----------------------------------------------------------------------------- |
649 LDLine* LDCondLine::demote() |
649 LDLine* LDCondLine::demote() |
650 { |
650 { |
651 LDLine* repl = new LDLine; |
651 LDLine* repl = new LDLine; |
652 |
652 |
653 for( int i = 0; i < repl->vertices(); ++i) |
653 for (int i = 0; i < repl->vertices(); ++i) |
654 repl->setVertex( i, getVertex( i)); |
654 repl->setVertex (i, getVertex (i)); |
655 |
655 |
656 repl->setColor( getColor()); |
656 repl->setColor (getColor()); |
657 |
657 |
658 replace( repl); |
658 replace (repl); |
659 return repl; |
659 return repl; |
660 } |
660 } |
661 |
661 |
662 // ============================================================================= |
662 // ============================================================================= |
663 // ----------------------------------------------------------------------------- |
663 // ----------------------------------------------------------------------------- |
664 LDObject* LDObject::fromID( int id) |
664 LDObject* LDObject::fromID (int id) |
665 { |
665 { |
666 for( LDObject* obj : g_LDObjects) |
666 for (LDObject* obj : g_LDObjects) |
667 if( obj->getID() == id) |
667 if (obj->getID() == id) |
668 return obj; |
668 return obj; |
669 |
669 |
670 return null; |
670 return null; |
671 } |
671 } |
672 |
672 |
673 // ============================================================================= |
673 // ============================================================================= |
674 // ----------------------------------------------------------------------------- |
674 // ----------------------------------------------------------------------------- |
675 str LDOverlay::raw() const |
675 str LDOverlay::raw() const |
676 { |
676 { |
677 return fmt( "0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
677 return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
678 getFileName(), getCamera(), getX(), getY(), getWidth(), getHeight()); |
678 getFileName(), getCamera(), getX(), getY(), getWidth(), getHeight()); |
679 } |
679 } |
680 |
680 |
681 void LDOverlay::invert() {} |
681 void LDOverlay::invert() {} |
682 |
682 |
683 // ============================================================================= |
683 // ============================================================================= |
684 // Hook the set accessors of certain properties to this changeProperty function. |
684 // Hook the set accessors of certain properties to this changeProperty function. |
685 // It takes care of history management so we can capture low-level changes, this |
685 // It takes care of history management so we can capture low-level changes, this |
686 // makes history stuff work out of the box. |
686 // makes history stuff work out of the box. |
687 // ----------------------------------------------------------------------------- |
687 // ----------------------------------------------------------------------------- |
688 template<class T> static void changeProperty( LDObject* obj, T* ptr, const T& val) |
688 template<class T> static void changeProperty (LDObject* obj, T* ptr, const T& val) |
689 { |
689 { |
690 long idx; |
690 long idx; |
691 |
691 |
692 if( *ptr == val) |
692 if (*ptr == val) |
693 return; |
693 return; |
694 |
694 |
695 if( obj->getFile() &&( idx = obj->getIndex()) != -1) |
695 if (obj->getFile() && (idx = obj->getIndex()) != -1) |
696 { |
696 { |
697 str before = obj->raw(); |
697 str before = obj->raw(); |
698 *ptr = val; |
698 *ptr = val; |
699 str after = obj->raw(); |
699 str after = obj->raw(); |
700 |
700 |
701 if( before != after) |
701 if (before != after) |
702 obj->getFile()->addToHistory( new EditHistory( idx, before, after)); |
702 obj->getFile()->addToHistory (new EditHistory (idx, before, after)); |
703 } |
703 } |
704 else |
704 else |
705 *ptr = val; |
705 *ptr = val; |
706 } |
706 } |
707 |
707 |
708 // ============================================================================= |
708 // ============================================================================= |
709 // ----------------------------------------------------------------------------- |
709 // ----------------------------------------------------------------------------- |
710 void LDObject::setColor( const int& val) |
710 void LDObject::setColor (const int& val) |
711 { |
711 { |
712 changeProperty( this, &m_Color, val); |
712 changeProperty (this, &m_Color, val); |
713 } |
713 } |
714 |
714 |
715 // ============================================================================= |
715 // ============================================================================= |
716 // ----------------------------------------------------------------------------- |
716 // ----------------------------------------------------------------------------- |
717 const vertex& LDObject::getVertex( int i) const |
717 const Vertex& LDObject::getVertex (int i) const |
718 { |
718 { |
719 return m_coords[i]->data(); |
719 return m_coords[i]->data(); |
720 } |
720 } |
721 |
721 |
722 // ============================================================================= |
722 // ============================================================================= |
723 // ----------------------------------------------------------------------------- |
723 // ----------------------------------------------------------------------------- |
724 void LDObject::setVertex( int i, const vertex& vert) |
724 void LDObject::setVertex (int i, const Vertex& vert) |
725 { |
725 { |
726 changeProperty( this, &m_coords[i], LDSharedVertex::getSharedVertex( vert)); |
726 changeProperty (this, &m_coords[i], LDSharedVertex::getSharedVertex (vert)); |
727 } |
727 } |
728 |
728 |
729 // ============================================================================= |
729 // ============================================================================= |
730 // ----------------------------------------------------------------------------- |
730 // ----------------------------------------------------------------------------- |
731 void LDMatrixObject::setPosition( const vertex& a) |
731 void LDMatrixObject::setPosition (const Vertex& a) |
732 { |
732 { |
733 changeProperty( getLinkPointer(), &m_Position, LDSharedVertex::getSharedVertex( a)); |
733 changeProperty (getLinkPointer(), &m_Position, LDSharedVertex::getSharedVertex (a)); |
734 } |
734 } |
735 |
735 |
736 // ============================================================================= |
736 // ============================================================================= |
737 // ----------------------------------------------------------------------------- |
737 // ----------------------------------------------------------------------------- |
738 void LDMatrixObject::setTransform( const matrix& val) |
738 void LDMatrixObject::setTransform (const Matrix& val) |
739 { |
739 { |
740 changeProperty( getLinkPointer(), &m_Transform, val); |
740 changeProperty (getLinkPointer(), &m_Transform, val); |
741 } |
741 } |
742 |
742 |
743 // ============================================================================= |
743 // ============================================================================= |
744 // ----------------------------------------------------------------------------- |
744 // ----------------------------------------------------------------------------- |
745 static QMap<vertex, LDSharedVertex*> g_sharedVerts; |
745 static QMap<Vertex, LDSharedVertex*> g_sharedVerts; |
746 |
746 |
747 LDSharedVertex* LDSharedVertex::getSharedVertex( const vertex& a) |
747 LDSharedVertex* LDSharedVertex::getSharedVertex (const Vertex& a) |
748 { |
748 { |
749 auto it = g_sharedVerts.find( a); |
749 auto it = g_sharedVerts.find (a); |
750 |
750 |
751 if( it == g_sharedVerts.end()) |
751 if (it == g_sharedVerts.end()) |
752 { |
752 { |
753 LDSharedVertex* v = new LDSharedVertex( a); |
753 LDSharedVertex* v = new LDSharedVertex (a); |
754 g_sharedVerts[a] = v; |
754 g_sharedVerts[a] = v; |
755 return v; |
755 return v; |
756 } |
756 } |
757 |
757 |
758 return *it; |
758 return *it; |
759 } |
759 } |
760 |
760 |
761 // ============================================================================= |
761 // ============================================================================= |
762 // ----------------------------------------------------------------------------- |
762 // ----------------------------------------------------------------------------- |
763 void LDSharedVertex::addRef( LDObject* a) |
763 void LDSharedVertex::addRef (LDObject* a) |
764 { |
764 { |
765 m_refs << a; |
765 m_refs << a; |
766 } |
766 } |
767 |
767 |
768 // ============================================================================= |
768 // ============================================================================= |
769 // ----------------------------------------------------------------------------- |
769 // ----------------------------------------------------------------------------- |
770 void LDSharedVertex::delRef( LDObject* a) |
770 void LDSharedVertex::delRef (LDObject* a) |
771 { |
771 { |
772 m_refs.removeOne( a); |
772 m_refs.removeOne (a); |
773 |
773 |
774 if( m_refs.empty()) |
774 if (m_refs.empty()) |
775 { |
775 { |
776 g_sharedVerts.remove( m_data); |
776 g_sharedVerts.remove (m_data); |
777 delete this; |
777 delete this; |
778 } |
778 } |
779 } |
779 } |
780 |
780 |
781 // ============================================================================= |
781 // ============================================================================= |
782 // ----------------------------------------------------------------------------- |
782 // ----------------------------------------------------------------------------- |
783 void LDObject::select() |
783 void LDObject::select() |
784 { |
784 { |
785 if( !getFile()) |
785 if (!getFile()) |
786 { |
786 { |
787 log( "Warning: Object #%1 cannot be selected as it is not assigned a file!\n", getID()); |
787 log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", getID()); |
788 return; |
788 return; |
789 } |
789 } |
790 |
790 |
791 getFile()->addToSelection( this); |
791 getFile()->addToSelection (this); |
792 } |
792 } |
793 |
793 |
794 // ============================================================================= |
794 // ============================================================================= |
795 // ----------------------------------------------------------------------------- |
795 // ----------------------------------------------------------------------------- |
796 void LDObject::unselect() |
796 void LDObject::unselect() |
797 { |
797 { |
798 if( !getFile()) |
798 if (!getFile()) |
799 { |
799 { |
800 log( "Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", getID()); |
800 log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", getID()); |
801 return; |
801 return; |
802 } |
802 } |
803 |
803 |
804 getFile()->removeFromSelection( this); |
804 getFile()->removeFromSelection (this); |
805 } |
805 } |
806 |
806 |
807 // ============================================================================= |
807 // ============================================================================= |
808 // ----------------------------------------------------------------------------- |
808 // ----------------------------------------------------------------------------- |
809 str getLicenseText( int id) |
809 str getLicenseText (int id) |
810 { |
810 { |
811 switch( id) |
811 switch (id) |
812 { |
812 { |
813 case 0: |
813 case 0: |
814 return CALicense; |
814 return CALicense; |
815 |
815 |
816 case 1: |
816 case 1: |