diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index cc0dc174..f798a127 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -22,6 +22,8 @@ struct PortWidget::Internal { bool overrideCreateCable = false; /** When dragging port, this is the grabbed end type of the cable. */ engine::Port::Type draggedType = engine::Port::INPUT; + /** Created when dragging starts, deleted when it ends. */ + history::ComplexAction* history = NULL; }; @@ -396,6 +398,14 @@ void PortWidget::onDragStart(const DragStartEvent& e) { internal->overrideCreateCable = false; }); + // Create ComplexAction + if (internal->history) { + delete internal->history; + internal->history = NULL; + } + internal->history = new history::ComplexAction; + internal->history->name = "move cable"; + CableWidget* cw = NULL; int mods = APP->window->getMods(); if (internal->overrideCreateCable || (mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { @@ -415,7 +425,6 @@ void PortWidget::onDragStart(const DragStartEvent& e) { cw->inputPort = cloneCw->inputPort; else cw->outputPort = cloneCw->outputPort; - cw->updateCable(); internal->draggedType = type; } } @@ -429,7 +438,7 @@ void PortWidget::onDragStart(const DragStartEvent& e) { // history::CableRemove history::CableRemove* h = new history::CableRemove; h->setCable(cw); - APP->history->push(h); + internal->history->push(h); // Reuse existing cable cw->getPort(type) = NULL; @@ -453,7 +462,6 @@ void PortWidget::onDragStart(const DragStartEvent& e) { // Set port cw->getPort(type) = this; - cw->updateCable(); internal->draggedType = (type == engine::Port::INPUT) ? engine::Port::OUTPUT : engine::Port::INPUT; } @@ -468,32 +476,32 @@ void PortWidget::onDragEnd(const DragEndEvent& e) { if (e.button != GLFW_MOUSE_BUTTON_LEFT) return; - std::vector cws = APP->scene->rack->getIncompleteCables(); - if (cws.empty()) + // Should never happen since it's created in onDragStart(). + if (!internal->history) return; - history::ComplexAction* h = new history::ComplexAction; - - for (CableWidget* cw : cws) { - if (cw->isComplete()) { - // history::CableAdd - history::CableAdd* hAdd = new history::CableAdd; - hAdd->setCable(cw); - h->push(hAdd); - } - else { - APP->scene->rack->removeCable(cw); - delete cw; - } + // Remove all incomplete cables + for (CableWidget* cw : APP->scene->rack->getIncompleteCables()) { + APP->scene->rack->removeCable(cw); + delete cw; } // Push history - if (h->isEmpty()) { - delete h; + if (internal->history->isEmpty()) { + // No history actions, don't push anything + delete internal->history; + } + else if (internal->history->actions.size() == 1) { + // Push single history action + APP->history->push(internal->history->actions[0]); + internal->history->actions.clear(); + delete internal->history; } else { - APP->history->push(h); + // Push ComplexAction + APP->history->push(internal->history); } + internal->history = NULL; } @@ -511,6 +519,7 @@ void PortWidget::onDragDrop(const DragDropEvent& e) { } for (CableWidget* cw : APP->scene->rack->getIncompleteCables()) { + // These should already be NULL because onDragLeave() is called immediately before onDragDrop(). cw->hoveredOutputPort = NULL; cw->hoveredInputPort = NULL; if (type == engine::Port::OUTPUT) { @@ -518,13 +527,25 @@ void PortWidget::onDragDrop(const DragDropEvent& e) { if (cw->inputPort && !APP->scene->rack->getCable(this, cw->inputPort)) { cw->outputPort = this; } + else { + continue; + } } else { if (cw->outputPort && !APP->scene->rack->getCable(cw->outputPort, this)) { cw->inputPort = this; } + else { + continue; + } } cw->updateCable(); + + history::CableAdd* h = new history::CableAdd; + h->setCable(cw); + pwOrigin->internal->history->push(h); + + // TODO Reject history if plugging into same port } }