| @@ -42,7 +42,7 @@ struct CableWidget : widget::Widget { | |||
| engine::Cable* getCable(); | |||
| math::Vec getInputPos(); | |||
| math::Vec getOutputPos(); | |||
| json_t* toJson(); | |||
| void mergeJson(json_t* rootJ); | |||
| void fromJson(json_t* rootJ); | |||
| void step() override; | |||
| void draw(const DrawArgs& args) override; | |||
| @@ -80,6 +80,7 @@ struct ModuleWidget : widget::OpaqueWidget { | |||
| json_t* toJson(); | |||
| void fromJson(json_t* rootJ); | |||
| void fromJsonAction(json_t* rootJ); | |||
| void copyClipboard(); | |||
| void pasteClipboardAction(); | |||
| void load(std::string filename); | |||
| @@ -47,6 +47,7 @@ struct RackWidget : widget::OpaqueWidget { | |||
| void clear(); | |||
| void mergeJson(json_t* rootJ); | |||
| void fromJson(json_t* rootJ); | |||
| void fromJsonAction(json_t* rootJ); | |||
| void pasteClipboardAction(); | |||
| // Module methods | |||
| @@ -213,13 +213,9 @@ math::Vec CableWidget::getOutputPos() { | |||
| } | |||
| } | |||
| json_t* CableWidget::toJson() { | |||
| json_t* rootJ = json_object(); | |||
| void CableWidget::mergeJson(json_t* rootJ) { | |||
| std::string s = color::toHexString(color); | |||
| json_object_set_new(rootJ, "color", json_string(s.c_str())); | |||
| return rootJ; | |||
| } | |||
| void CableWidget::fromJson(json_t* rootJ) { | |||
| @@ -472,14 +472,40 @@ void ModuleWidget::onDragHover(const DragHoverEvent& e) { | |||
| } | |||
| json_t* ModuleWidget::toJson() { | |||
| json_t* moduleJ = APP->engine->moduleToJson(module); | |||
| return moduleJ; | |||
| json_t* rootJ = APP->engine->moduleToJson(module); | |||
| return rootJ; | |||
| } | |||
| void ModuleWidget::fromJson(json_t* rootJ) { | |||
| APP->engine->moduleFromJson(module, rootJ); | |||
| } | |||
| void ModuleWidget::fromJsonAction(json_t* rootJ) { | |||
| // Don't use IDs from JSON | |||
| json_object_del(rootJ, "id"); | |||
| json_object_del(rootJ, "leftModuleId"); | |||
| json_object_del(rootJ, "rightModuleId"); | |||
| json_t* oldModuleJ = toJson(); | |||
| try { | |||
| fromJson(rootJ); | |||
| } | |||
| catch (Exception& e) { | |||
| WARN("%s", e.what()); | |||
| json_decref(oldModuleJ); | |||
| return; | |||
| } | |||
| // history::ModuleChange | |||
| history::ModuleChange* h = new history::ModuleChange; | |||
| h->name = "paste module preset"; | |||
| h->moduleId = module->id; | |||
| h->oldModuleJ = oldModuleJ; | |||
| h->newModuleJ = toJson(); | |||
| APP->history->push(h); | |||
| } | |||
| void ModuleWidget::copyClipboard() { | |||
| json_t* moduleJ = toJson(); | |||
| DEFER({json_decref(moduleJ);}); | |||
| @@ -503,29 +529,7 @@ void ModuleWidget::pasteClipboardAction() { | |||
| } | |||
| DEFER({json_decref(moduleJ);}); | |||
| // Don't use IDs from JSON | |||
| json_object_del(moduleJ, "id"); | |||
| json_object_del(moduleJ, "leftModuleId"); | |||
| json_object_del(moduleJ, "rightModuleId"); | |||
| json_t* oldModuleJ = toJson(); | |||
| try { | |||
| fromJson(moduleJ); | |||
| } | |||
| catch (Exception& e) { | |||
| WARN("%s", e.what()); | |||
| json_decref(oldModuleJ); | |||
| return; | |||
| } | |||
| // history::ModuleChange | |||
| history::ModuleChange* h = new history::ModuleChange; | |||
| h->name = "paste module preset"; | |||
| h->moduleId = module->id; | |||
| h->oldModuleJ = oldModuleJ; | |||
| h->newModuleJ = toJson(); | |||
| APP->history->push(h); | |||
| fromJsonAction(moduleJ); | |||
| } | |||
| void ModuleWidget::load(std::string filename) { | |||
| @@ -259,10 +259,7 @@ void RackWidget::mergeJson(json_t* rootJ) { | |||
| continue; | |||
| } | |||
| // Merge CableWidget JSON | |||
| json_t* cwJ = cw->toJson(); | |||
| json_object_update(cableJ, cwJ); | |||
| json_decref(cwJ); | |||
| cw->mergeJson(cableJ); | |||
| } | |||
| } | |||
| @@ -278,7 +275,6 @@ void RackWidget::fromJson(json_t* rootJ) { | |||
| legacyV05 = true; | |||
| } | |||
| // modules | |||
| json_t* modulesJ = json_object_get(rootJ, "modules"); | |||
| if (!modulesJ) | |||
| @@ -359,20 +355,8 @@ void RackWidget::fromJson(json_t* rootJ) { | |||
| } | |||
| } | |||
| void RackWidget::pasteClipboardAction() { | |||
| const char* moduleJson = glfwGetClipboardString(APP->window->win); | |||
| if (!moduleJson) { | |||
| WARN("Could not get text from clipboard."); | |||
| return; | |||
| } | |||
| json_error_t error; | |||
| json_t* moduleJ = json_loads(moduleJson, 0, &error); | |||
| if (!moduleJ) { | |||
| WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||
| return; | |||
| } | |||
| DEFER({json_decref(moduleJ);}); | |||
| void RackWidget::fromJsonAction(json_t* rootJ) { | |||
| json_t* moduleJ = rootJ; | |||
| // Because we are creating a new module, we don't want to use the IDs from the JSON. | |||
| json_object_del(moduleJ, "id"); | |||
| @@ -399,6 +383,24 @@ void RackWidget::pasteClipboardAction() { | |||
| APP->history->push(h); | |||
| } | |||
| void RackWidget::pasteClipboardAction() { | |||
| const char* moduleJson = glfwGetClipboardString(APP->window->win); | |||
| if (!moduleJson) { | |||
| WARN("Could not get text from clipboard."); | |||
| return; | |||
| } | |||
| json_error_t error; | |||
| json_t* moduleJ = json_loads(moduleJson, 0, &error); | |||
| if (!moduleJ) { | |||
| WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||
| return; | |||
| } | |||
| DEFER({json_decref(moduleJ);}); | |||
| fromJsonAction(moduleJ); | |||
| } | |||
| static void RackWidget_updateExpanders(RackWidget* that) { | |||
| for (widget::Widget* w : that->internal->moduleContainer->children) { | |||
| math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); | |||
| @@ -726,11 +728,7 @@ json_t* RackWidget::selectedModulesToJson() { | |||
| continue; | |||
| json_t* cableJ = cable->toJson(); | |||
| // Merge CableWidget JSON | |||
| json_t* cwJ = cw->toJson(); | |||
| json_object_update(cableJ, cwJ); | |||
| json_decref(cwJ); | |||
| cw->mergeJson(cableJ); | |||
| json_array_append_new(cablesJ, cableJ); | |||
| } | |||