| @@ -286,8 +286,11 @@ struct Module { | |||||
| onSampleRateChange(); | onSampleRateChange(); | ||||
| } | } | ||||
| struct ExpanderChangeEvent {}; | |||||
| /** Called after the Engine sample rate changes. | |||||
| struct ExpanderChangeEvent { | |||||
| /** False for left, true for right. */ | |||||
| bool side; | |||||
| }; | |||||
| /** Called after an expander is added, removed, or changed on either the left or right side of the Module. | |||||
| */ | */ | ||||
| virtual void onExpanderChange(const ExpanderChangeEvent& e) {} | virtual void onExpanderChange(const ExpanderChangeEvent& e) {} | ||||
| @@ -335,7 +335,7 @@ void RackWidget::pastePresetClipboardAction() { | |||||
| } | } | ||||
| } | } | ||||
| static void RackWidget_updateAdjacent(RackWidget* that) { | |||||
| static void RackWidget_updateExpanders(RackWidget* that) { | |||||
| for (widget::Widget* w : that->moduleContainer->children) { | for (widget::Widget* w : that->moduleContainer->children) { | ||||
| math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); | math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); | ||||
| math::Vec pRight = w->box.getTopRight().div(RACK_GRID_SIZE).round(); | math::Vec pRight = w->box.getTopRight().div(RACK_GRID_SIZE).round(); | ||||
| @@ -375,7 +375,7 @@ void RackWidget::addModule(ModuleWidget* m) { | |||||
| assert(m->box.size.y == RACK_GRID_HEIGHT); | assert(m->box.size.y == RACK_GRID_HEIGHT); | ||||
| moduleContainer->addChild(m); | moduleContainer->addChild(m); | ||||
| RackWidget_updateAdjacent(this); | |||||
| RackWidget_updateExpanders(this); | |||||
| } | } | ||||
| void RackWidget::addModuleAtMouse(ModuleWidget* mw) { | void RackWidget::addModuleAtMouse(ModuleWidget* mw) { | ||||
| @@ -418,7 +418,7 @@ bool RackWidget::requestModulePos(ModuleWidget* mw, math::Vec pos) { | |||||
| // Accept requested position | // Accept requested position | ||||
| mw->setPosition(mwBox.pos); | mw->setPosition(mwBox.pos); | ||||
| RackWidget_updateAdjacent(this); | |||||
| RackWidget_updateExpanders(this); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -520,7 +520,7 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { | |||||
| xLimit = newPos.x + w->box.size.x; | xLimit = newPos.x + w->box.size.x; | ||||
| } | } | ||||
| RackWidget_updateAdjacent(this); | |||||
| RackWidget_updateExpanders(this); | |||||
| } | } | ||||
| ModuleWidget* RackWidget::getModule(int64_t moduleId) { | ModuleWidget* RackWidget::getModule(int64_t moduleId) { | ||||
| @@ -226,17 +226,27 @@ struct Engine::Internal { | |||||
| }; | }; | ||||
| static void Engine_updateExpander(Engine* that, Module::Expander* expander) { | |||||
| if (expander->moduleId >= 0) { | |||||
| if (!expander->module || expander->module->id != expander->moduleId) { | |||||
| expander->module = that->getModule(expander->moduleId); | |||||
| static void Engine_updateExpander(Engine* that, Module* module, bool side) { | |||||
| Module::Expander& expander = side ? module->rightExpander : module->leftExpander; | |||||
| Module* oldExpanderModule = expander.module; | |||||
| if (expander.moduleId >= 0) { | |||||
| if (!expander.module || expander.module->id != expander.moduleId) { | |||||
| expander.module = that->getModule(expander.moduleId); | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (expander->module) { | |||||
| expander->module = NULL; | |||||
| if (expander.module) { | |||||
| expander.module = NULL; | |||||
| } | } | ||||
| } | } | ||||
| if (expander.module != oldExpanderModule) { | |||||
| // Trigger ExpanderChangeEvent event | |||||
| Module::ExpanderChangeEvent e; | |||||
| e.side = side; | |||||
| module->onExpanderChange(e); | |||||
| } | |||||
| } | } | ||||
| @@ -571,8 +581,8 @@ void Engine::step(int frames) { | |||||
| // Update expander pointers | // Update expander pointers | ||||
| for (Module* module : internal->modules) { | for (Module* module : internal->modules) { | ||||
| Engine_updateExpander(this, &module->leftExpander); | |||||
| Engine_updateExpander(this, &module->rightExpander); | |||||
| Engine_updateExpander(this, module, false); | |||||
| Engine_updateExpander(this, module, true); | |||||
| } | } | ||||
| // Launch workers | // Launch workers | ||||
| @@ -153,7 +153,8 @@ void PatchManager::saveTemplateDialog() { | |||||
| void PatchManager::saveAutosave() { | void PatchManager::saveAutosave() { | ||||
| INFO("Saving autosave"); | |||||
| std::string patchPath = system::join(asset::autosavePath, "patch.json"); | |||||
| INFO("Saving autosave %s", patchPath.c_str()); | |||||
| json_t* rootJ = toJson(); | json_t* rootJ = toJson(); | ||||
| if (!rootJ) | if (!rootJ) | ||||
| return; | return; | ||||
| @@ -161,7 +162,6 @@ void PatchManager::saveAutosave() { | |||||
| // Write to temporary path and then rename it to the correct path | // Write to temporary path and then rename it to the correct path | ||||
| system::createDirectories(asset::autosavePath); | system::createDirectories(asset::autosavePath); | ||||
| std::string patchPath = system::join(asset::autosavePath, "patch.json"); | |||||
| std::string tmpPath = patchPath + ".tmp"; | std::string tmpPath = patchPath + ".tmp"; | ||||
| FILE* file = std::fopen(tmpPath.c_str(), "w"); | FILE* file = std::fopen(tmpPath.c_str(), "w"); | ||||
| if (!file) { | if (!file) { | ||||
| @@ -265,8 +265,8 @@ void PatchManager::loadTemplateDialog() { | |||||
| void PatchManager::loadAutosave() { | void PatchManager::loadAutosave() { | ||||
| INFO("Loading autosave"); | |||||
| std::string patchPath = system::join(asset::autosavePath, "patch.json"); | std::string patchPath = system::join(asset::autosavePath, "patch.json"); | ||||
| INFO("Loading autosave %s", patchPath.c_str()); | |||||
| FILE* file = std::fopen(patchPath.c_str(), "r"); | FILE* file = std::fopen(patchPath.c_str(), "r"); | ||||
| if (!file) { | if (!file) { | ||||
| // Exit silently | // Exit silently | ||||