src/gui_editactions.cpp

changeset 192
c414924a647c
parent 191
9bb6a17305ad
child 194
cfe9ae5f1124
equal deleted inserted replaced
191:9bb6a17305ad 192:c414924a647c
99 g_curfile->insertObj (idx, copy); 99 g_curfile->insertObj (idx, copy);
100 g_win->sel ().push_back (copy); 100 g_win->sel ().push_back (copy);
101 } 101 }
102 102
103 History::addEntry (new AddHistory (historyIndices, historyCopies, AddHistory::Paste)); 103 History::addEntry (new AddHistory (historyIndices, historyCopies, AddHistory::Paste));
104 g_win->refresh (); 104 g_win->fullRefresh ();
105 g_win->scrollToSelection (); 105 g_win->scrollToSelection ();
106 } 106 }
107 107
108 // ============================================================================= 108 // =============================================================================
109 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 109 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
166 g_curfile->forgetObject (obj); 166 g_curfile->forgetObject (obj);
167 delete obj; 167 delete obj;
168 } 168 }
169 169
170 History::addEntry (new InlineHistory (bitIndices, refIndices, refs, bDeep)); 170 History::addEntry (new InlineHistory (bitIndices, refIndices, refs, bDeep));
171 g_win->refresh (); 171 g_win->fullRefresh ();
172 } 172 }
173 173
174 MAKE_ACTION (inlineContents, "Inline", "inline", "Inline selected subfiles.", CTRL (I)) { 174 MAKE_ACTION (inlineContents, "Inline", "inline", "Inline selected subfiles.", CTRL (I)) {
175 doInline (false); 175 doInline (false);
176 } 176 }
226 226
227 critical (errmsg); 227 critical (errmsg);
228 } 228 }
229 229
230 History::addEntry (history); 230 History::addEntry (history);
231 g_win->refresh (); 231 g_win->fullRefresh ();
232 } 232 }
233 233
234 // ======================================================================================================================================= 234 // =======================================================================================================================================
235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
236 // ======================================================================================================================================= 236 // =======================================================================================================================================
269 // Delete this quad now, it has been split. 269 // Delete this quad now, it has been split.
270 delete obj; 270 delete obj;
271 } 271 }
272 272
273 History::addEntry (new QuadSplitHistory (ulaIndices, paCopies)); 273 History::addEntry (new QuadSplitHistory (ulaIndices, paCopies));
274 g_win->refresh (); 274 g_win->fullRefresh ();
275 } 275 }
276 276
277 // ============================================================================= 277 // =============================================================================
278 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 278 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
279 // ============================================================================= 279 // =============================================================================
314 obj->color = dColor; 314 obj->color = dColor;
315 } 315 }
316 } 316 }
317 317
318 History::addEntry (new SetColorHistory (ulaIndices, daColors, dColor)); 318 History::addEntry (new SetColorHistory (ulaIndices, daColors, dColor));
319 g_win->refresh (); 319 g_win->fullRefresh ();
320 } 320 }
321 } 321 }
322 322
323 // ============================================================================= 323 // =============================================================================
324 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 324 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
365 paObjs.push_back (lines[i]->clone ()); 365 paObjs.push_back (lines[i]->clone ());
366 } 366 }
367 } 367 }
368 368
369 History::addEntry (new AddHistory (ulaIndices, paObjs)); 369 History::addEntry (new AddHistory (ulaIndices, paObjs));
370 g_win->refresh (); 370 g_win->fullRefresh ();
371 } 371 }
372 372
373 // ============================================================================= 373 // =============================================================================
374 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 374 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
375 // ============================================================================= 375 // =============================================================================
395 } 395 }
396 } 396 }
397 397
398 if (ulaIndices.size() > 0) { 398 if (ulaIndices.size() > 0) {
399 History::addEntry (new AddHistory (ulaIndices, paObjs)); 399 History::addEntry (new AddHistory (ulaIndices, paObjs));
400 g_win->refresh (); 400 g_win->fullRefresh ();
401 } 401 }
402 } 402 }
403 403
404 // ============================================================================= 404 // =============================================================================
405 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 405 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
456 ulaIndices.push_back (obj->getIndex (g_curfile)); 456 ulaIndices.push_back (obj->getIndex (g_curfile));
457 obj->move (vVector); 457 obj->move (vVector);
458 } 458 }
459 459
460 History::addEntry (new MoveHistory (ulaIndices, vVector)); 460 History::addEntry (new MoveHistory (ulaIndices, vVector));
461 g_win->refresh (); 461 g_win->fullRefresh ();
462 } 462 }
463 463
464 MAKE_ACTION (moveXNeg, "Move -X", "move-x-neg", "Move selected objects negative on the X axis.", KEY (Left)) { 464 MAKE_ACTION (moveXNeg, "Move -X", "move-x-neg", "Move selected objects negative on the X axis.", KEY (Left)) {
465 doMoveObjects ({-1, 0, 0}); 465 doMoveObjects ({-1, 0, 0});
466 } 466 }
496 // them and wrap them into a ComboHistory, which allows storage of multiple 496 // them and wrap them into a ComboHistory, which allows storage of multiple
497 // simultaneous edits with different type. This is what we ultimately store into 497 // simultaneous edits with different type. This is what we ultimately store into
498 // History. 498 // History.
499 // ============================================================================= 499 // =============================================================================
500 MAKE_ACTION (invert, "Invert", "invert", "Reverse the winding of given objects.", CTRL_SHIFT (W)) { 500 MAKE_ACTION (invert, "Invert", "invert", "Reverse the winding of given objects.", CTRL_SHIFT (W)) {
501 std::vector<LDObject*> paSelection = g_win->sel (); 501 std::vector<LDObject*> sel = g_win->sel ();
502 std::vector<HistoryEntry*> paHistory; 502 ComboHistory* history = new ComboHistory;
503 503
504 for (LDObject* obj : paSelection) { 504 for (LDObject* obj : sel) {
505 // For the objects we end up editing, we store information into these 505 *history << obj->invert ();
506 // variables and we store them into an EditHistory after the switch 506 g_win->R ()->compileObject (obj);
507 // block. Subfile and radial management is stored into the history 507 }
508 // list immediately. 508
509 ulong ulHistoryIndex = obj->getIndex (g_curfile); 509 printf ("%lu entries\n", history->numEntries ());
510 LDObject* pOldCopy, *pNewCopy; 510 if (history->numEntries () > 0) {
511 bool bEdited = false; 511 History::addEntry (history);
512 512 g_win->buildObjList ();
513 switch (obj->getType ()) { 513 } else
514 case LDObject::Line: 514 delete history;
515 case LDObject::CondLine:
516 {
517 // For lines, we swap the vertices. I don't think that a
518 // cond-line's control points need to be swapped, do they?
519 LDLine* pLine = static_cast<LDLine*> (obj);
520 vertex vTemp = pLine->coords[0];
521
522 pOldCopy = pLine->clone ();
523 pLine->coords[0] = pLine->coords[1];
524 pLine->coords[1] = vTemp;
525 pNewCopy = pLine->clone ();
526 bEdited = true;
527 }
528 break;
529
530 case LDObject::Triangle:
531 {
532 // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1.
533 // Thus, we swap 1 and 2.
534 LDTriangle* pTri = static_cast<LDTriangle*> (obj);
535 vertex vTemp = pTri->coords[1];
536
537 pOldCopy = pTri->clone ();
538 pTri->coords[1] = pTri->coords[2];
539 pTri->coords[2] = vTemp;
540 pNewCopy = pTri->clone ();
541 bEdited = true;
542 }
543 break;
544
545 case LDObject::Quad:
546 {
547 // Quad: 0 -> 1 -> 2 -> 3
548 // rev: 0 -> 3 -> 2 -> 1
549 // Thus, we swap 1 and 3.
550 LDQuad* pQuad = static_cast<LDQuad*> (obj);
551 vertex vTemp = pQuad->coords[1];
552
553 pOldCopy = pQuad->clone ();
554 pQuad->coords[1] = pQuad->coords[3];
555 pQuad->coords[3] = vTemp;
556 pNewCopy = pQuad->clone ();
557 bEdited = true;
558 }
559 break;
560
561 case LDObject::Subfile:
562 case LDObject::Radial:
563 {
564 // Subfiles and radials are inverted when they're prefixed with
565 // a BFC INVERTNEXT statement. Thus we need to toggle this status.
566 // For flat primitives it's sufficient that the determinant is
567 // flipped but I don't have a method for checking flatness yet.
568 // Food for thought...
569
570 bool inverted = false;
571 ulong idx = obj->getIndex (g_curfile);
572
573 if (idx > 0) {
574 LDObject* prev = g_curfile->object (idx - 1);
575 LDBFC* bfc = dynamic_cast<LDBFC*> (prev);
576
577 if (bfc && bfc->type == LDBFC::InvertNext) {
578 // Object is prefixed with an invertnext, thus remove it.
579 paHistory.push_back (new DelHistory ({idx - 1}, {bfc->clone ()}));
580
581 inverted = true;
582 g_curfile->forgetObject (bfc);
583 delete bfc;
584 }
585 }
586
587 if (!inverted) {
588 // Not inverted, thus prefix it with a new invertnext.
589 LDBFC* bfc = new LDBFC (LDBFC::InvertNext);
590 g_curfile->insertObj (idx, bfc);
591
592 paHistory.push_back (new AddHistory ({idx}, {bfc->clone ()}));
593 }
594 }
595 break;
596
597 default:
598 break;
599 }
600
601 // If we edited this object, store the EditHistory based on collected
602 // information now.
603 if (bEdited == true)
604 paHistory.push_back (new EditHistory ({ulHistoryIndex}, {pOldCopy}, {pNewCopy}));
605 }
606
607 if (paHistory.size () > 0) {
608 History::addEntry (new ComboHistory (paHistory));
609 g_win->refresh ();
610 }
611 } 515 }
612 516
613 // ============================================================================= 517 // =============================================================================
614 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 518 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
615 // ============================================================================= 519 // =============================================================================
670 v->move (-origin); 574 v->move (-origin);
671 v->transform (transform, g_origin); 575 v->transform (transform, g_origin);
672 v->move (origin); 576 v->move (origin);
673 } 577 }
674 578
675 g_win->refresh (); 579 g_win->fullRefresh ();
676 } 580 }
677 581
678 MAKE_ACTION (rotateXPos, "Rotate +X", "rotate-x-pos", "Rotate objects around X axis", CTRL (Right)) { 582 MAKE_ACTION (rotateXPos, "Rotate +X", "rotate-x-pos", "Rotate objects around X axis", CTRL (Right)) {
679 doRotate (1, 0, 0); 583 doRotate (1, 0, 0);
680 } 584 }
708 for (LDObject* obj : g_win->sel ()) 612 for (LDObject* obj : g_win->sel ())
709 for (short i = 0; i < obj->vertices (); ++i) 613 for (short i = 0; i < obj->vertices (); ++i)
710 for (const Axis ax : g_Axes) 614 for (const Axis ax : g_Axes)
711 obj->coords[i][ax] = atof (fmt ("%.3f", obj->coords[i][ax])); 615 obj->coords[i][ax] = atof (fmt ("%.3f", obj->coords[i][ax]));
712 616
713 g_win->refresh (); 617 g_win->fullRefresh ();
714 } 618 }
715 619
716 // ============================================================================= 620 // =============================================================================
717 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 621 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
718 // ============================================================================= 622 // =============================================================================
731 newCopies.push_back (obj->clone ()); 635 newCopies.push_back (obj->clone ());
732 } 636 }
733 637
734 if (indices.size () > 0) { 638 if (indices.size () > 0) {
735 History::addEntry (new EditHistory (indices, oldCopies, newCopies)); 639 History::addEntry (new EditHistory (indices, oldCopies, newCopies));
736 g_win->refresh (); 640 g_win->fullRefresh ();
737 } 641 }
738 } 642 }
739 643
740 // ============================================================================= 644 // =============================================================================
741 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 645 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
753 } 657 }
754 658
755 // ========================================================================================================================================= 659 // =========================================================================================================================================
756 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 660 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
757 // ========================================================================================================================================= 661 // =========================================================================================================================================
662 static CheckBoxGroup<Axis>* makeAxesBox () {
663 CheckBoxGroup<Axis>* cbg_axes = new CheckBoxGroup<Axis> ("Axes", Qt::Horizontal);
664 cbg_axes->addCheckBox ("X", X);
665 cbg_axes->addCheckBox ("Y", Y);
666 cbg_axes->addCheckBox ("Z", Z);
667 return cbg_axes;
668 }
669
758 class ReplaceCoordsDialog : public QDialog { 670 class ReplaceCoordsDialog : public QDialog {
759 public: 671 public:
760 explicit ReplaceCoordsDialog (QWidget* parent = null, Qt::WindowFlags f = 0) : QDialog (parent, f) { 672 explicit ReplaceCoordsDialog (QWidget* parent = null, Qt::WindowFlags f = 0) : QDialog (parent, f) {
761 cbg_axes = new CheckBoxGroup<Axis> ("Axes", Qt::Horizontal); 673 cbg_axes = makeAxesBox ();
762 cbg_axes->addCheckBox ("X", X);
763 cbg_axes->addCheckBox ("Y", Y);
764 cbg_axes->addCheckBox ("Z", Z);
765 674
766 lb_search = new QLabel ("Search:"); 675 lb_search = new QLabel ("Search:");
767 lb_replacement = new QLabel ("Replacement:"); 676 lb_replacement = new QLabel ("Replacement:");
768 677
769 dsb_search = new QDoubleSpinBox; 678 dsb_search = new QDoubleSpinBox;
811 vector<Axis> sel = dlg.axes (); 720 vector<Axis> sel = dlg.axes ();
812 721
813 EditHistory* history = new EditHistory; 722 EditHistory* history = new EditHistory;
814 723
815 for (LDObject* obj : g_win->sel ()) { 724 for (LDObject* obj : g_win->sel ()) {
816 bool altered = false;
817 LDObject* copy = obj->clone (); 725 LDObject* copy = obj->clone ();
818 726
819 for (short i = 0; i < obj->vertices (); ++i) 727 for (short i = 0; i < obj->vertices (); ++i)
820 for (Axis ax : sel) { 728 for (Axis ax : sel) {
821 if (obj->coords[i][ax] == search) { 729 if (obj->coords[i][ax] == search) {
822 obj->coords[i][ax] = replacement; 730 obj->coords[i][ax] = replacement;
823 altered = true;
824 } 731 }
825 } 732 }
826 733
734 history->addEntry (copy, obj, obj->getIndex (g_curfile));
735
736 delete copy;
737 }
738
739 History::addEntry (history);
740 g_win->fullRefresh ();
741 }
742
743 // =========================================================================================================================================
744 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
745 // =========================================================================================================================================
746 class FlipDialog : public QDialog {
747 public:
748 explicit FlipDialog (QWidget* parent = 0, Qt::WindowFlags f = 0) : QDialog (parent, f) {
749 cbg_axes = makeAxesBox ();
750
751 QVBoxLayout* layout = new QVBoxLayout;
752 layout->addWidget (cbg_axes);
753 layout->addWidget (makeButtonBox (*this));
754 setLayout (layout);
755 }
756
757 vector<Axis> axes () { return cbg_axes->checkedValues (); }
758
759 private:
760 CheckBoxGroup<Axis>* cbg_axes;
761 };
762
763 MAKE_ACTION (flip, "Flip", "flip", "Flip coordinates", CTRL_SHIFT (F)) {
764 FlipDialog dlg;
765
766 if (!dlg.exec ())
767 return;
768
769 EditHistory* history = new EditHistory;
770 vector<Axis> sel = dlg.axes ();
771
772 for (LDObject* obj : g_win->sel ()) {
773 bool altered = false;
774 LDObject* copy = obj->clone ();
775
776 for (short i = 0; i < obj->vertices (); ++i)
777 for (Axis ax : sel) {
778 obj->coords[i][ax] *= -1;
779 altered = true;
780 }
781
827 if (altered) 782 if (altered)
828 history->addEntry (copy, obj, obj->getIndex (g_curfile)); 783 history->addEntry (copy, obj, obj->getIndex (g_curfile));
829 784
830 delete copy; 785 delete copy;
831 } 786 }
832 787
833 History::addEntry (history); 788 History::addEntry (history);
834 g_win->refresh (); 789 g_win->fullRefresh ();
835 } 790 }

mercurial