| @@ -20,9 +20,9 @@ ifdef ARCH_LIN | |||||
| SOURCES += dep/osdialog/osdialog_gtk2.c | SOURCES += dep/osdialog/osdialog_gtk2.c | ||||
| build/dep/osdialog/osdialog_gtk2.c.o: FLAGS += $(shell pkg-config --cflags gtk+-2.0) | build/dep/osdialog/osdialog_gtk2.c.o: FLAGS += $(shell pkg-config --cflags gtk+-2.0) | ||||
| LDFLAGS += -rdynamic \ | |||||
| LDFLAGS += -rdynamic -Wl,--whole-archive \ | |||||
| dep/lib/libGLEW.a dep/lib/libglfw3.a dep/lib/libjansson.a dep/lib/libcurl.a dep/lib/libssl.a dep/lib/libcrypto.a dep/lib/libzip.a dep/lib/libz.a dep/lib/libspeexdsp.a dep/lib/libsamplerate.a dep/lib/librtmidi.a dep/lib/librtaudio.a \ | dep/lib/libGLEW.a dep/lib/libglfw3.a dep/lib/libjansson.a dep/lib/libcurl.a dep/lib/libssl.a dep/lib/libcrypto.a dep/lib/libzip.a dep/lib/libz.a dep/lib/libspeexdsp.a dep/lib/libsamplerate.a dep/lib/librtmidi.a dep/lib/librtaudio.a \ | ||||
| -lpthread -lGL -ldl -lX11 -lasound -ljack \ | |||||
| -Wl,--no-whole-archive -lpthread -lGL -ldl -lX11 -lasound -ljack \ | |||||
| $(shell pkg-config --libs gtk+-2.0) | $(shell pkg-config --libs gtk+-2.0) | ||||
| TARGET := Rack | TARGET := Rack | ||||
| endif | endif | ||||
| @@ -12,21 +12,24 @@ namespace app { | |||||
| struct Knob : ParamWidget { | struct Knob : ParamWidget { | ||||
| /** Multiplier for mouse movement to adjust knob value */ | /** Multiplier for mouse movement to adjust knob value */ | ||||
| float speed = 1.0; | float speed = 1.0; | ||||
| float oldValue = 0.f; | |||||
| /** Drag horizontally instead of vertically. */ | |||||
| bool horizontal = false; | |||||
| /** Enables per-sample value smoothing while dragging. */ | |||||
| bool smooth = true; | bool smooth = true; | ||||
| /** Enable snapping at integer values */ | |||||
| /** DEPRECATED. Use `ParamQuantity::snapEnabled`. */ | |||||
| bool snap = false; | bool snap = false; | ||||
| float snapValue = NAN; | |||||
| /** Drag horizontally instead of vertically */ | |||||
| bool horizontal = false; | |||||
| /** Value of the knob before dragging. */ | |||||
| float oldValue = 0.f; | |||||
| /** Fractional value between the param's value and the dragged knob position. */ | |||||
| float snapDelta = 0.f; | |||||
| void init() override; | |||||
| void onHover(const event::Hover& e) override; | void onHover(const event::Hover& e) override; | ||||
| void onButton(const event::Button& e) override; | void onButton(const event::Button& e) override; | ||||
| void onDragStart(const event::DragStart& e) override; | void onDragStart(const event::DragStart& e) override; | ||||
| void onDragEnd(const event::DragEnd& e) override; | void onDragEnd(const event::DragEnd& e) override; | ||||
| void onDragMove(const event::DragMove& e) override; | void onDragMove(const event::DragMove& e) override; | ||||
| void reset() override; | |||||
| void randomize() override; | |||||
| }; | }; | ||||
| @@ -13,9 +13,11 @@ namespace app { | |||||
| /** Manages an engine::Param on a ModuleWidget. */ | /** Manages an engine::Param on a ModuleWidget. */ | ||||
| struct ParamWidget : widget::OpaqueWidget { | struct ParamWidget : widget::OpaqueWidget { | ||||
| engine::ParamQuantity* paramQuantity = NULL; | engine::ParamQuantity* paramQuantity = NULL; | ||||
| float dirtyValue = NAN; | |||||
| ui::Tooltip* tooltip = NULL; | ui::Tooltip* tooltip = NULL; | ||||
| /** For triggering the Change event. `*/ | |||||
| float lastValue = NAN; | |||||
| virtual void init() {} | |||||
| void step() override; | void step() override; | ||||
| void draw(const DrawArgs& args) override; | void draw(const DrawArgs& args) override; | ||||
| @@ -26,8 +28,6 @@ struct ParamWidget : widget::OpaqueWidget { | |||||
| void createContextMenu(); | void createContextMenu(); | ||||
| void resetAction(); | void resetAction(); | ||||
| virtual void reset() {} | |||||
| virtual void randomize() {} | |||||
| }; | }; | ||||
| @@ -19,12 +19,11 @@ struct Switch : ParamWidget { | |||||
| bool momentaryPressed = false; | bool momentaryPressed = false; | ||||
| bool momentaryReleased = false; | bool momentaryReleased = false; | ||||
| void init() override; | |||||
| void step() override; | void step() override; | ||||
| void onDoubleClick(const event::DoubleClick& e) override; | void onDoubleClick(const event::DoubleClick& e) override; | ||||
| void onDragStart(const event::DragStart& e) override; | void onDragStart(const event::DragStart& e) override; | ||||
| void onDragEnd(const event::DragEnd& e) override; | void onDragEnd(const event::DragEnd& e) override; | ||||
| void reset() override; | |||||
| void randomize() override; | |||||
| }; | }; | ||||
| @@ -65,7 +65,9 @@ struct Engine { | |||||
| // Params | // Params | ||||
| void setParam(Module* module, int paramId, float value); | void setParam(Module* module, int paramId, float value); | ||||
| float getParam(Module* module, int paramId); | float getParam(Module* module, int paramId); | ||||
| /** Requests the parameter to smoothly change toward `value`. */ | |||||
| void setSmoothParam(Module* module, int paramId, float value); | void setSmoothParam(Module* module, int paramId, float value); | ||||
| /** Returns the target value before smoothing. */ | |||||
| float getSmoothParam(Module* module, int paramId); | float getSmoothParam(Module* module, int paramId); | ||||
| // ParamHandles | // ParamHandles | ||||
| @@ -38,13 +38,16 @@ struct ParamQuantity : Quantity { | |||||
| int displayPrecision = 5; | int displayPrecision = 5; | ||||
| /** An optional one-sentence description of the parameter. */ | /** An optional one-sentence description of the parameter. */ | ||||
| std::string description; | std::string description; | ||||
| /** Enables parameter resetting when the module is reset. | |||||
| /** Enables parameter resetting when the module or parameter itself is reset. | |||||
| */ | */ | ||||
| bool resetEnabled = true; | bool resetEnabled = true; | ||||
| /** Enables parameter randomization when the module is randomized. | /** Enables parameter randomization when the module is randomized. | ||||
| Unbounded (infinite) parameters are not randomizable, regardless of this setting. | Unbounded (infinite) parameters are not randomizable, regardless of this setting. | ||||
| */ | */ | ||||
| bool randomizeEnabled = true; | bool randomizeEnabled = true; | ||||
| /** Rounds values to the nearest integer. */ | |||||
| bool snapEnabled = false; | |||||
| Param* getParam(); | Param* getParam(); | ||||
| /** Request to the engine to smoothly set the value */ | /** Request to the engine to smoothly set the value */ | ||||
| @@ -62,6 +62,7 @@ TParamWidget* createParam(math::Vec pos, engine::Module* module, int paramId) { | |||||
| if (module) { | if (module) { | ||||
| o->paramQuantity = module->paramQuantities[paramId]; | o->paramQuantity = module->paramQuantities[paramId]; | ||||
| } | } | ||||
| o->init(); | |||||
| return o; | return o; | ||||
| } | } | ||||
| @@ -56,10 +56,12 @@ void CableWidget::setCable(engine::Cable* cable) { | |||||
| app::ModuleWidget* outputModule = APP->scene->rack->getModule(cable->outputModule->id); | app::ModuleWidget* outputModule = APP->scene->rack->getModule(cable->outputModule->id); | ||||
| assert(outputModule); | assert(outputModule); | ||||
| outputPort = outputModule->getOutput(cable->outputId); | outputPort = outputModule->getOutput(cable->outputId); | ||||
| assert(outputPort); | |||||
| app::ModuleWidget* inputModule = APP->scene->rack->getModule(cable->inputModule->id); | app::ModuleWidget* inputModule = APP->scene->rack->getModule(cable->inputModule->id); | ||||
| assert(inputModule); | assert(inputModule); | ||||
| inputPort = inputModule->getInput(cable->inputId); | inputPort = inputModule->getInput(cable->inputId); | ||||
| assert(inputPort); | |||||
| } | } | ||||
| else { | else { | ||||
| outputPort = NULL; | outputPort = NULL; | ||||
| @@ -12,6 +12,14 @@ namespace app { | |||||
| static const float KNOB_SENSITIVITY = 0.0015f; | static const float KNOB_SENSITIVITY = 0.0015f; | ||||
| void Knob::init() { | |||||
| ParamWidget::init(); | |||||
| if (paramQuantity) { | |||||
| if (snap) | |||||
| paramQuantity->snapEnabled = true; | |||||
| } | |||||
| } | |||||
| void Knob::onHover(const event::Hover& e) { | void Knob::onHover(const event::Hover& e) { | ||||
| math::Vec c = box.size.div(2); | math::Vec c = box.size.div(2); | ||||
| float dist = e.pos.minus(c).norm(); | float dist = e.pos.minus(c).norm(); | ||||
| @@ -34,9 +42,7 @@ void Knob::onDragStart(const event::DragStart& e) { | |||||
| if (paramQuantity) { | if (paramQuantity) { | ||||
| oldValue = paramQuantity->getSmoothValue(); | oldValue = paramQuantity->getSmoothValue(); | ||||
| if (snap) { | |||||
| snapValue = paramQuantity->getValue(); | |||||
| } | |||||
| snapDelta = 0.f; | |||||
| } | } | ||||
| APP->window->cursorLock(); | APP->window->cursorLock(); | ||||
| @@ -81,22 +87,25 @@ void Knob::onDragMove(const event::DragMove& e) { | |||||
| delta *= speed; | delta *= speed; | ||||
| delta *= range; | delta *= range; | ||||
| // Drag slower if mod is held | |||||
| // Drag slower if Mod is held | |||||
| int mods = APP->window->getMods(); | int mods = APP->window->getMods(); | ||||
| if ((mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | if ((mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | ||||
| delta /= 16.f; | delta /= 16.f; | ||||
| } | } | ||||
| // Drag even slower if mod+shift is held | |||||
| // Drag even slower if Mod-Shift is held | |||||
| if ((mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | if ((mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | ||||
| delta /= 256.f; | delta /= 256.f; | ||||
| } | } | ||||
| if (snap) { | |||||
| snapValue += delta; | |||||
| snapValue = math::clamp(snapValue, paramQuantity->getMinValue(), paramQuantity->getMaxValue()); | |||||
| paramQuantity->setValue(std::round(snapValue)); | |||||
| if (paramQuantity->snapEnabled) { | |||||
| // Replace delta with an accumulated delta since the last integer knob. | |||||
| snapDelta += delta; | |||||
| delta = std::trunc(snapDelta); | |||||
| snapDelta -= delta; | |||||
| } | } | ||||
| else if (smooth) { | |||||
| // Set value | |||||
| if (smooth) { | |||||
| paramQuantity->setSmoothValue(paramQuantity->getSmoothValue() + delta); | paramQuantity->setSmoothValue(paramQuantity->getSmoothValue() + delta); | ||||
| } | } | ||||
| else { | else { | ||||
| @@ -107,23 +116,6 @@ void Knob::onDragMove(const event::DragMove& e) { | |||||
| ParamWidget::onDragMove(e); | ParamWidget::onDragMove(e); | ||||
| } | } | ||||
| void Knob::reset() { | |||||
| if (paramQuantity && paramQuantity->isBounded()) { | |||||
| paramQuantity->reset(); | |||||
| oldValue = snapValue = paramQuantity->getValue(); | |||||
| } | |||||
| } | |||||
| void Knob::randomize() { | |||||
| if (paramQuantity && paramQuantity->isBounded()) { | |||||
| float value = math::rescale(random::uniform(), 0.f, 1.f, paramQuantity->getMinValue(), paramQuantity->getMaxValue()); | |||||
| if (snap) | |||||
| value = std::round(value); | |||||
| paramQuantity->setValue(value); | |||||
| oldValue = snapValue = paramQuantity->getValue(); | |||||
| } | |||||
| } | |||||
| } // namespace app | } // namespace app | ||||
| } // namespace rack | } // namespace rack | ||||
| @@ -668,9 +668,6 @@ void ModuleWidget::resetAction() { | |||||
| h->moduleId = module->id; | h->moduleId = module->id; | ||||
| h->oldModuleJ = toJson(); | h->oldModuleJ = toJson(); | ||||
| for (ParamWidget* param : params) { | |||||
| param->reset(); | |||||
| } | |||||
| APP->engine->resetModule(module); | APP->engine->resetModule(module); | ||||
| h->newModuleJ = toJson(); | h->newModuleJ = toJson(); | ||||
| @@ -686,9 +683,6 @@ void ModuleWidget::randomizeAction() { | |||||
| h->moduleId = module->id; | h->moduleId = module->id; | ||||
| h->oldModuleJ = toJson(); | h->oldModuleJ = toJson(); | ||||
| for (ParamWidget* param : params) { | |||||
| param->randomize(); | |||||
| } | |||||
| APP->engine->randomizeModule(module); | APP->engine->randomizeModule(module); | ||||
| h->newModuleJ = toJson(); | h->newModuleJ = toJson(); | ||||
| @@ -754,12 +748,13 @@ void ModuleWidget::cloneAction() { | |||||
| void ModuleWidget::disableAction() { | void ModuleWidget::disableAction() { | ||||
| assert(module); | assert(module); | ||||
| APP->engine->disableModule(module, !module->disabled); | |||||
| // history::ModuleDisable | // history::ModuleDisable | ||||
| history::ModuleDisable* h = new history::ModuleDisable; | history::ModuleDisable* h = new history::ModuleDisable; | ||||
| h->moduleId = module->id; | h->moduleId = module->id; | ||||
| h->disabled = !module->disabled; | |||||
| h->disabled = module->disabled; | |||||
| APP->history->push(h); | APP->history->push(h); | ||||
| h->redo(); | |||||
| } | } | ||||
| void ModuleWidget::removeAction() { | void ModuleWidget::removeAction() { | ||||
| @@ -113,12 +113,12 @@ struct ParamUnmapItem : ui::MenuItem { | |||||
| void ParamWidget::step() { | void ParamWidget::step() { | ||||
| if (paramQuantity) { | if (paramQuantity) { | ||||
| float value = paramQuantity->getValue(); | |||||
| float value = paramQuantity->getSmoothValue(); | |||||
| // Trigger change event when paramQuantity value changes | // Trigger change event when paramQuantity value changes | ||||
| if (value != dirtyValue) { | |||||
| dirtyValue = value; | |||||
| if (value != lastValue) { | |||||
| event::Change eChange; | event::Change eChange; | ||||
| onChange(eChange); | onChange(eChange); | ||||
| lastValue = value; | |||||
| } | } | ||||
| } | } | ||||
| @@ -218,11 +218,9 @@ void ParamWidget::createContextMenu() { | |||||
| } | } | ||||
| void ParamWidget::resetAction() { | void ParamWidget::resetAction() { | ||||
| if (paramQuantity && paramQuantity->isBounded()) { | |||||
| if (paramQuantity && paramQuantity->resetEnabled) { | |||||
| float oldValue = paramQuantity->getValue(); | float oldValue = paramQuantity->getValue(); | ||||
| reset(); | |||||
| // Here's another way of doing it, but either works. | |||||
| // paramQuantity->getParam()->reset(); | |||||
| paramQuantity->reset(); | |||||
| float newValue = paramQuantity->getValue(); | float newValue = paramQuantity->getValue(); | ||||
| if (oldValue != newValue) { | if (oldValue != newValue) { | ||||
| @@ -573,7 +573,10 @@ void RackWidget::clearCablesAction() { | |||||
| complexAction->push(h); | complexAction->push(h); | ||||
| } | } | ||||
| APP->history->push(complexAction); | |||||
| if (!complexAction->isEmpty()) | |||||
| APP->history->push(complexAction); | |||||
| else | |||||
| delete complexAction; | |||||
| clearCables(); | clearCables(); | ||||
| } | } | ||||
| @@ -34,12 +34,14 @@ void SvgKnob::setSvg(std::shared_ptr<Svg> svg) { | |||||
| void SvgKnob::onChange(const event::Change& e) { | void SvgKnob::onChange(const event::Change& e) { | ||||
| // Re-transform the widget::TransformWidget | // Re-transform the widget::TransformWidget | ||||
| if (paramQuantity) { | if (paramQuantity) { | ||||
| float value = paramQuantity->getScaledValue(); | |||||
| float angle; | float angle; | ||||
| if (paramQuantity->isBounded()) { | if (paramQuantity->isBounded()) { | ||||
| angle = math::rescale(paramQuantity->getScaledValue(), 0.f, 1.f, minAngle, maxAngle); | |||||
| angle = math::rescale(value, 0.f, 1.f, minAngle, maxAngle); | |||||
| } | } | ||||
| else { | else { | ||||
| angle = math::rescale(paramQuantity->getValue(), -1.f, 1.f, minAngle, maxAngle); | |||||
| // Center unbounded knobs | |||||
| angle = math::rescale(value, -1.f, 1.f, minAngle, maxAngle); | |||||
| } | } | ||||
| angle = std::fmod(angle, 2 * M_PI); | angle = std::fmod(angle, 2 * M_PI); | ||||
| tw->identity(); | tw->identity(); | ||||
| @@ -9,6 +9,17 @@ namespace rack { | |||||
| namespace app { | namespace app { | ||||
| void Switch::init() { | |||||
| ParamWidget::init(); | |||||
| if (paramQuantity) { | |||||
| paramQuantity->snapEnabled = true; | |||||
| if (momentary) { | |||||
| paramQuantity->resetEnabled = false; | |||||
| paramQuantity->randomizeEnabled = false; | |||||
| } | |||||
| } | |||||
| } | |||||
| void Switch::step() { | void Switch::step() { | ||||
| if (momentaryPressed) { | if (momentaryPressed) { | ||||
| momentaryPressed = false; | momentaryPressed = false; | ||||
| @@ -75,19 +86,6 @@ void Switch::onDragEnd(const event::DragEnd& e) { | |||||
| } | } | ||||
| } | } | ||||
| void Switch::reset() { | |||||
| if (paramQuantity && !momentary) { | |||||
| paramQuantity->reset(); | |||||
| } | |||||
| } | |||||
| void Switch::randomize() { | |||||
| if (paramQuantity && !momentary) { | |||||
| float value = paramQuantity->getMinValue() + std::floor(random::uniform() * (paramQuantity->getRange() + 1)); | |||||
| paramQuantity->setValue(value); | |||||
| } | |||||
| } | |||||
| } // namespace app | } // namespace app | ||||
| } // namespace rack | } // namespace rack | ||||
| @@ -539,7 +539,7 @@ void Engine::addModule(Module* module) { | |||||
| if (paramHandle->moduleId == module->id) | if (paramHandle->moduleId == module->id) | ||||
| paramHandle->module = module; | paramHandle->module = module; | ||||
| } | } | ||||
| DEBUG("Added module %d to engine", module->id); | |||||
| // DEBUG("Added module %d to engine", module->id); | |||||
| } | } | ||||
| @@ -582,7 +582,7 @@ void Engine::removeModule(Module* module) { | |||||
| internal->primaryModule = NULL; | internal->primaryModule = NULL; | ||||
| // Remove module | // Remove module | ||||
| internal->modules.erase(it); | internal->modules.erase(it); | ||||
| DEBUG("Removed module %d to engine", module->id); | |||||
| // DEBUG("Removed module %d to engine", module->id); | |||||
| } | } | ||||
| @@ -736,7 +736,7 @@ void Engine::addCable(Cable* cable) { | |||||
| e.portId = cable->outputId; | e.portId = cable->outputId; | ||||
| cable->outputModule->onPortChange(e); | cable->outputModule->onPortChange(e); | ||||
| } | } | ||||
| DEBUG("Added cable %d to engine", cable->id); | |||||
| // DEBUG("Added cable %d to engine", cable->id); | |||||
| } | } | ||||
| @@ -772,7 +772,7 @@ void Engine::removeCable(Cable* cable) { | |||||
| e.portId = cable->outputId; | e.portId = cable->outputId; | ||||
| cable->outputModule->onPortChange(e); | cable->outputModule->onPortChange(e); | ||||
| } | } | ||||
| DEBUG("Removed cable %d to engine", cable->id); | |||||
| // DEBUG("Removed cable %d to engine", cable->id); | |||||
| } | } | ||||
| @@ -979,7 +979,6 @@ void Engine::fromJson(json_t* rootJ) { | |||||
| Cable* cable = new Cable; | Cable* cable = new Cable; | ||||
| try { | try { | ||||
| cable->fromJson(cableJ); | cable->fromJson(cableJ); | ||||
| // DEBUG("%p %d %p %d", cable->inputModule, cable->inputId, cable->) | |||||
| addCable(cable); | addCable(cable); | ||||
| } | } | ||||
| catch (Exception& e) { | catch (Exception& e) { | ||||
| @@ -180,11 +180,10 @@ void Module::fromJson(json_t* rootJ) { | |||||
| void Module::onReset(const ResetEvent& e) { | void Module::onReset(const ResetEvent& e) { | ||||
| // Reset all parameters | // Reset all parameters | ||||
| assert(params.size() == paramQuantities.size()); | |||||
| for (int i = 0; i < (int) params.size(); i++) { | |||||
| if (!paramQuantities[i]->resetEnabled) | |||||
| for (ParamQuantity* pq : paramQuantities) { | |||||
| if (!pq->resetEnabled) | |||||
| continue; | continue; | ||||
| paramQuantities[i]->reset(); | |||||
| pq->reset(); | |||||
| } | } | ||||
| // Call deprecated event | // Call deprecated event | ||||
| onReset(); | onReset(); | ||||
| @@ -193,11 +192,10 @@ void Module::onReset(const ResetEvent& e) { | |||||
| void Module::onRandomize(const RandomizeEvent& e) { | void Module::onRandomize(const RandomizeEvent& e) { | ||||
| // Randomize all parameters | // Randomize all parameters | ||||
| assert(params.size() == paramQuantities.size()); | |||||
| for (int i = 0; i < (int) params.size(); i++) { | |||||
| if (!paramQuantities[i]->randomizeEnabled) | |||||
| for (ParamQuantity* pq : paramQuantities) { | |||||
| if (!pq->randomizeEnabled) | |||||
| continue; | continue; | ||||
| paramQuantities[i]->randomize(); | |||||
| pq->randomize(); | |||||
| } | } | ||||
| // Call deprecated event | // Call deprecated event | ||||
| onRandomize(); | onRandomize(); | ||||
| @@ -17,6 +17,8 @@ void ParamQuantity::setSmoothValue(float smoothValue) { | |||||
| if (!module) | if (!module) | ||||
| return; | return; | ||||
| smoothValue = math::clampSafe(smoothValue, getMinValue(), getMaxValue()); | smoothValue = math::clampSafe(smoothValue, getMinValue(), getMaxValue()); | ||||
| if (snapEnabled) | |||||
| smoothValue = std::round(smoothValue); | |||||
| APP->engine->setSmoothParam(module, paramId, smoothValue); | APP->engine->setSmoothParam(module, paramId, smoothValue); | ||||
| } | } | ||||
| @@ -30,6 +32,8 @@ void ParamQuantity::setValue(float value) { | |||||
| if (!module) | if (!module) | ||||
| return; | return; | ||||
| value = math::clampSafe(value, getMinValue(), getMaxValue()); | value = math::clampSafe(value, getMinValue(), getMaxValue()); | ||||
| if (snapEnabled) | |||||
| value = std::round(value); | |||||
| APP->engine->setParam(module, paramId, value); | APP->engine->setParam(module, paramId, value); | ||||
| } | } | ||||
| @@ -54,11 +54,8 @@ void ModuleAdd::setModule(app::ModuleWidget* mw) { | |||||
| void ModuleAdd::undo() { | void ModuleAdd::undo() { | ||||
| app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId); | app::ModuleWidget* mw = APP->scene->rack->getModule(moduleId); | ||||
| assert(mw); | assert(mw); | ||||
| engine::Module* module = mw->module; | |||||
| APP->scene->rack->removeModule(mw); | APP->scene->rack->removeModule(mw); | ||||
| delete mw; | delete mw; | ||||
| APP->engine->removeModule(module); | |||||
| delete module; | |||||
| } | } | ||||
| void ModuleAdd::redo() { | void ModuleAdd::redo() { | ||||
| @@ -66,6 +63,7 @@ void ModuleAdd::redo() { | |||||
| module->id = moduleId; | module->id = moduleId; | ||||
| module->fromJson(moduleJ); | module->fromJson(moduleJ); | ||||
| APP->engine->addModule(module); | APP->engine->addModule(module); | ||||
| app::ModuleWidget* mw = model->createModuleWidget(module); | app::ModuleWidget* mw = model->createModuleWidget(module); | ||||
| mw->box.pos = pos; | mw->box.pos = pos; | ||||
| APP->scene->rack->addModule(mw); | APP->scene->rack->addModule(mw); | ||||
| @@ -130,6 +128,7 @@ void ParamChange::redo() { | |||||
| void CableAdd::setCable(app::CableWidget* cw) { | void CableAdd::setCable(app::CableWidget* cw) { | ||||
| assert(cw); | |||||
| assert(cw->cable); | assert(cw->cable); | ||||
| assert(cw->cable->id >= 0); | assert(cw->cable->id >= 0); | ||||
| cableId = cw->cable->id; | cableId = cw->cable->id; | ||||
| @@ -147,11 +146,6 @@ void CableAdd::undo() { | |||||
| assert(cw); | assert(cw); | ||||
| APP->scene->rack->removeCable(cw); | APP->scene->rack->removeCable(cw); | ||||
| delete cw; | delete cw; | ||||
| engine::Cable* cable = APP->engine->getCable(cableId); | |||||
| assert(cable); | |||||
| APP->engine->removeCable(cable); | |||||
| delete cable; | |||||
| } | } | ||||
| void CableAdd::redo() { | void CableAdd::redo() { | ||||