30 |
30 |
31 // ============================================================================= |
31 // ============================================================================= |
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
33 // ============================================================================= |
33 // ============================================================================= |
34 // LDObject constructors |
34 // LDObject constructors |
35 LDObject::LDObject() { |
35 LDObject::LDObject () : |
36 qObjListEntry = null; |
36 m_hidden (false), |
37 setParent (null); |
37 m_selected (false), |
38 m_hidden = false; |
38 m_parent (null), |
39 m_selected = false; |
39 m_file (null), |
40 m_glinit = false; |
40 qObjListEntry (null), |
41 |
41 m_glinit (false) |
|
42 { |
42 // Determine ID |
43 // Determine ID |
43 int id = 1; // 0 is invalid |
44 qint32 id = 1; // 0 is invalid |
44 |
45 |
45 for (LDObject* obj : g_LDObjects) |
46 for (LDObject* obj : g_LDObjects) |
46 if (obj->id() >= id) |
47 if (obj->id() >= id) |
47 id = obj->id() + 1; |
48 id = obj->id() + 1; |
48 |
49 |
189 |
190 |
190 // ============================================================================= |
191 // ============================================================================= |
191 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
192 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
192 // ============================================================================= |
193 // ============================================================================= |
193 void LDObject::replace (LDObject* other) { |
194 void LDObject::replace (LDObject* other) { |
194 long idx = getIndex (currentFile()); |
195 long idx = getIndex(); |
195 assert (idx != -1); |
196 assert (idx != -1); |
196 |
197 |
197 // Replace the instance of the old object with the new object |
198 // Replace the instance of the old object with the new object |
198 currentFile()->setObject (idx, other); |
199 LDOpenFile::current()->setObject (idx, other); |
199 |
200 |
200 // Remove the old object |
201 // Remove the old object |
201 delete this; |
202 delete this; |
202 } |
203 } |
203 |
204 |
204 // ============================================================================= |
205 // ============================================================================= |
205 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
206 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
206 // ============================================================================= |
207 // ============================================================================= |
207 void LDObject::swap (LDObject* other) { |
208 void LDObject::swap (LDObject* other) { |
208 for (LDObject*& obj : *currentFile()) { |
209 for (LDObject*& obj : *LDOpenFile::current()) { |
209 if (obj == this) |
210 if (obj == this) |
210 obj = other; |
211 obj = other; |
211 elif (obj == other) |
212 elif (obj == other) |
212 obj = this; |
213 obj = this; |
213 } |
214 } |
214 |
215 |
215 currentFile()->addToHistory (new SwapHistory (id(), other->id())); |
216 LDOpenFile::current()->addToHistory (new SwapHistory (id(), other->id())); |
216 } |
217 } |
217 |
218 |
218 LDLineObject::LDLineObject (vertex v1, vertex v2) { |
219 LDLineObject::LDLineObject (vertex v1, vertex v2) { |
219 setVertex (0, v1); |
220 setVertex (0, v1); |
220 setVertex (1, v2); |
221 setVertex (1, v2); |
330 } |
331 } |
331 |
332 |
332 // ============================================================================= |
333 // ============================================================================= |
333 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
334 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
334 // ============================================================================= |
335 // ============================================================================= |
335 long LDObject::getIndex (LDOpenFile* file) const { |
336 long LDObject::getIndex() const { |
336 for (ulong i = 0; i < file->numObjs(); ++i) |
337 #ifndef RELEASE |
337 if (file->obj (i) == this) |
338 assert (file() != null); |
|
339 #endif |
|
340 |
|
341 for (ulong i = 0; i < file()->numObjs(); ++i) |
|
342 if (file()->obj (i) == this) |
338 return i; |
343 return i; |
339 |
344 |
340 return -1; |
345 return -1; |
341 } |
346 } |
342 |
347 |
351 vector<LDObject*> objsToCompile; |
356 vector<LDObject*> objsToCompile; |
352 |
357 |
353 for (long i = start; i != end; i += incr) { |
358 for (long i = start; i != end; i += incr) { |
354 LDObject* obj = objs[i]; |
359 LDObject* obj = objs[i]; |
355 |
360 |
356 const long idx = obj->getIndex (currentFile()), |
361 const long idx = obj->getIndex(), |
357 target = idx + (up ? -1 : 1); |
362 target = idx + (up ? -1 : 1); |
358 |
363 |
359 if ((up && idx == 0) || (!up && idx == (long) (currentFile()->objs().size() - 1))) { |
364 if ((up && idx == 0) || (!up && idx == (long) (LDOpenFile::current()->objs().size() - 1))) { |
360 // One of the objects hit the extrema. If this happens, this should be the first |
365 // One of the objects hit the extrema. If this happens, this should be the first |
361 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
366 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
362 // abort the entire operation. |
367 // abort the entire operation. |
363 assert (i == start); |
368 assert (i == start); |
364 return; |
369 return; |
365 } |
370 } |
366 |
371 |
367 objsToCompile << obj; |
372 objsToCompile << obj; |
368 objsToCompile << currentFile()->obj (target); |
373 objsToCompile << LDOpenFile::current()->obj (target); |
369 |
374 |
370 obj->swap (currentFile()->obj (target)); |
375 obj->swap (LDOpenFile::current()->obj (target)); |
371 } |
376 } |
372 |
377 |
373 objsToCompile.makeUnique(); |
378 objsToCompile.makeUnique(); |
374 |
379 |
375 // The objects need to be recompiled, otherwise their pick lists are left with |
380 // The objects need to be recompiled, otherwise their pick lists are left with |
435 return it; |
440 return it; |
436 } |
441 } |
437 |
442 |
438 // ============================================================================= |
443 // ============================================================================= |
439 LDObject* LDObject::next() const { |
444 LDObject* LDObject::next() const { |
440 long idx = getIndex (currentFile()); |
445 long idx = getIndex(); |
441 assert (idx != -1); |
446 assert (idx != -1); |
442 |
447 |
443 if (idx == (long) currentFile()->numObjs() - 1) |
448 if (idx == (long) LDOpenFile::current()->numObjs() - 1) |
444 return null; |
449 return null; |
445 |
450 |
446 return currentFile()->obj (idx + 1); |
451 return LDOpenFile::current()->obj (idx + 1); |
447 } |
452 } |
448 |
453 |
449 // ============================================================================= |
454 // ============================================================================= |
450 LDObject* LDObject::prev() const { |
455 LDObject* LDObject::prev() const { |
451 long idx = getIndex (currentFile()); |
456 long idx = getIndex(); |
452 assert (idx != -1); |
457 assert (idx != -1); |
453 |
458 |
454 if (idx == 0) |
459 if (idx == 0) |
455 return null; |
460 return null; |
456 |
461 |
457 return currentFile()->obj (idx - 1); |
462 return LDOpenFile::current()->obj (idx - 1); |
458 } |
463 } |
459 |
464 |
460 // ============================================================================= |
465 // ============================================================================= |
461 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
466 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
462 // ============================================================================= |
467 // ============================================================================= |
550 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
555 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
551 // For flat primitives it's sufficient that the determinant is |
556 // For flat primitives it's sufficient that the determinant is |
552 // flipped but I don't have a method for checking flatness yet. |
557 // flipped but I don't have a method for checking flatness yet. |
553 // Food for thought... |
558 // Food for thought... |
554 |
559 |
555 ulong idx = getIndex (currentFile()); |
560 ulong idx = getIndex(); |
556 |
561 |
557 if (idx > 0) { |
562 if (idx > 0) { |
558 LDBFCObject* bfc = dynamic_cast<LDBFCObject*> (prev()); |
563 LDBFCObject* bfc = dynamic_cast<LDBFCObject*> (prev()); |
559 |
564 |
560 if (bfc && bfc->type == LDBFCObject::InvertNext) { |
565 if (bfc && bfc->type == LDBFCObject::InvertNext) { |
561 // This is prefixed with an invertnext, thus remove it. |
566 // This is prefixed with an invertnext, thus remove it. |
562 currentFile()->forgetObject (bfc); |
567 LDOpenFile::current()->forgetObject (bfc); |
563 delete bfc; |
568 delete bfc; |
564 return; |
569 return; |
565 } |
570 } |
566 } |
571 } |
567 |
572 |
568 // Not inverted, thus prefix it with a new invertnext. |
573 // Not inverted, thus prefix it with a new invertnext. |
569 LDBFCObject* bfc = new LDBFCObject (LDBFCObject::InvertNext); |
574 LDBFCObject* bfc = new LDBFCObject (LDBFCObject::InvertNext); |
570 currentFile()->insertObj (idx, bfc); |
575 LDOpenFile::current()->insertObj (idx, bfc); |
571 } |
576 } |
572 |
577 |
573 static void invertLine (LDObject* line) { |
578 static void invertLine (LDObject* line) { |
574 // For lines, we swap the vertices. I don't think that a |
579 // For lines, we swap the vertices. I don't think that a |
575 // cond-line's control points need to be swapped, do they? |
580 // cond-line's control points need to be swapped, do they? |
626 // It takes care of history management so we can capture low-level changes, this |
631 // It takes care of history management so we can capture low-level changes, this |
627 // makes history stuff work out of the box. |
632 // makes history stuff work out of the box. |
628 template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) { |
633 template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) { |
629 long idx; |
634 long idx; |
630 |
635 |
631 if ((idx = obj->getIndex (currentFile())) != -1) { |
636 if (obj->file() && (idx = obj->getIndex()) != -1) { |
632 str before = obj->raw(); |
637 str before = obj->raw(); |
633 *ptr = val; |
638 *ptr = val; |
634 str after = obj->raw(); |
639 str after = obj->raw(); |
635 |
640 |
636 currentFile()->addToHistory (new EditHistory (idx, before, after)); |
641 LDOpenFile::current()->addToHistory (new EditHistory (idx, before, after)); |
637 } else |
642 } else |
638 *ptr = val; |
643 *ptr = val; |
639 } |
644 } |
640 |
645 |
641 READ_ACCESSOR (short, LDObject::color) { |
646 READ_ACCESSOR (short, LDObject::color) { |