| @@ -42,7 +42,7 @@ struct CableWidget : widget::Widget { | |||||
| engine::Cable* getCable(); | engine::Cable* getCable(); | ||||
| math::Vec getInputPos(); | math::Vec getInputPos(); | ||||
| math::Vec getOutputPos(); | math::Vec getOutputPos(); | ||||
| json_t* toJson(); | |||||
| void mergeJson(json_t* rootJ); | |||||
| void fromJson(json_t* rootJ); | void fromJson(json_t* rootJ); | ||||
| void step() override; | void step() override; | ||||
| void draw(const DrawArgs& args) override; | void draw(const DrawArgs& args) override; | ||||
| @@ -80,6 +80,7 @@ struct ModuleWidget : widget::OpaqueWidget { | |||||
| json_t* toJson(); | json_t* toJson(); | ||||
| void fromJson(json_t* rootJ); | void fromJson(json_t* rootJ); | ||||
| void fromJsonAction(json_t* rootJ); | |||||
| void copyClipboard(); | void copyClipboard(); | ||||
| void pasteClipboardAction(); | void pasteClipboardAction(); | ||||
| void load(std::string filename); | void load(std::string filename); | ||||
| @@ -47,6 +47,7 @@ struct RackWidget : widget::OpaqueWidget { | |||||
| void clear(); | void clear(); | ||||
| void mergeJson(json_t* rootJ); | void mergeJson(json_t* rootJ); | ||||
| void fromJson(json_t* rootJ); | void fromJson(json_t* rootJ); | ||||
| void fromJsonAction(json_t* rootJ); | |||||
| void pasteClipboardAction(); | void pasteClipboardAction(); | ||||
| // Module methods | // 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); | std::string s = color::toHexString(color); | ||||
| json_object_set_new(rootJ, "color", json_string(s.c_str())); | json_object_set_new(rootJ, "color", json_string(s.c_str())); | ||||
| return rootJ; | |||||
| } | } | ||||
| void CableWidget::fromJson(json_t* rootJ) { | void CableWidget::fromJson(json_t* rootJ) { | ||||
| @@ -472,14 +472,40 @@ void ModuleWidget::onDragHover(const DragHoverEvent& e) { | |||||
| } | } | ||||
| json_t* ModuleWidget::toJson() { | 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) { | void ModuleWidget::fromJson(json_t* rootJ) { | ||||
| APP->engine->moduleFromJson(module, 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() { | void ModuleWidget::copyClipboard() { | ||||
| json_t* moduleJ = toJson(); | json_t* moduleJ = toJson(); | ||||
| DEFER({json_decref(moduleJ);}); | DEFER({json_decref(moduleJ);}); | ||||
| @@ -503,29 +529,7 @@ void ModuleWidget::pasteClipboardAction() { | |||||
| } | } | ||||
| DEFER({json_decref(moduleJ);}); | 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) { | void ModuleWidget::load(std::string filename) { | ||||
| @@ -259,10 +259,7 @@ void RackWidget::mergeJson(json_t* rootJ) { | |||||
| continue; | 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; | legacyV05 = true; | ||||
| } | } | ||||
| // modules | // modules | ||||
| json_t* modulesJ = json_object_get(rootJ, "modules"); | json_t* modulesJ = json_object_get(rootJ, "modules"); | ||||
| if (!modulesJ) | 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. | // Because we are creating a new module, we don't want to use the IDs from the JSON. | ||||
| json_object_del(moduleJ, "id"); | json_object_del(moduleJ, "id"); | ||||
| @@ -399,6 +383,24 @@ void RackWidget::pasteClipboardAction() { | |||||
| APP->history->push(h); | 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) { | static void RackWidget_updateExpanders(RackWidget* that) { | ||||
| for (widget::Widget* w : that->internal->moduleContainer->children) { | for (widget::Widget* w : that->internal->moduleContainer->children) { | ||||
| math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); | math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); | ||||
| @@ -726,11 +728,7 @@ json_t* RackWidget::selectedModulesToJson() { | |||||
| continue; | continue; | ||||
| json_t* cableJ = cable->toJson(); | 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); | json_array_append_new(cablesJ, cableJ); | ||||
| } | } | ||||