Browse Source

Fix module paste key command. Fix crash when deleting module selection.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
95ed0bb5c5
7 changed files with 55 additions and 30 deletions
  1. +3
    -2
      include/app/ModuleWidget.hpp
  2. +1
    -0
      include/engine/Cable.hpp
  3. +1
    -1
      src/app/MenuBar.cpp
  4. +16
    -10
      src/app/ModuleWidget.cpp
  5. +7
    -2
      src/app/RackWidget.cpp
  6. +22
    -15
      src/app/Scene.cpp
  7. +5
    -0
      src/engine/Cable.cpp

+ 3
- 2
include/app/ModuleWidget.hpp View File

@@ -79,9 +79,10 @@ struct ModuleWidget : widget::OpaqueWidget {


json_t* toJson(); json_t* toJson();
void fromJson(json_t* rootJ); void fromJson(json_t* rootJ);
void pasteJsonAction(json_t* rootJ);
/** Returns whether paste was successful. */
bool pasteJsonAction(json_t* rootJ);
void copyClipboard(); void copyClipboard();
void pasteClipboardAction();
bool pasteClipboardAction();
void load(std::string filename); void load(std::string filename);
void loadAction(std::string filename); void loadAction(std::string filename);
void loadTemplate(); void loadTemplate();


+ 1
- 0
include/engine/Cable.hpp View File

@@ -20,6 +20,7 @@ struct Cable {


json_t* toJson(); json_t* toJson();
void fromJson(json_t* rootJ); void fromJson(json_t* rootJ);
INTERNAL static void jsonStripIds(json_t* rootJ);
}; };






+ 1
- 1
src/app/MenuBar.cpp View File

@@ -757,7 +757,7 @@ struct HelpButton : MenuButton {
APP->scene->addChild(tipWindowCreate()); APP->scene->addChild(tipWindowCreate());
})); }));


menu->addChild(createMenuItem("Manual", "F1", [=]() {
menu->addChild(createMenuItem("User manual", "F1", [=]() {
system::openBrowser("https://vcvrack.com/manual/"); system::openBrowser("https://vcvrack.com/manual/");
})); }));




+ 16
- 10
src/app/ModuleWidget.cpp View File

@@ -312,8 +312,9 @@ void ModuleWidget::onHoverKey(const HoverKeyEvent& e) {
e.consume(this); e.consume(this);
} }
if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
pasteClipboardAction();
e.consume(this);
if (pasteClipboardAction()) {
e.consume(this);
}
} }
if (e.keyName == "d" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "d" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
cloneAction(); cloneAction();
@@ -342,7 +343,9 @@ void ModuleWidget::onHoverKey(const HoverKeyEvent& e) {
return; return;
} }
if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
system::openBrowser(model->getManualUrl());
std::string manualUrl = model->getManualUrl();
if (!manualUrl.empty())
system::openBrowser(manualUrl);
e.consume(this); e.consume(this);
} }
} }
@@ -468,7 +471,7 @@ void ModuleWidget::fromJson(json_t* moduleJ) {
APP->engine->moduleFromJson(module, moduleJ); APP->engine->moduleFromJson(module, moduleJ);
} }


void ModuleWidget::pasteJsonAction(json_t* moduleJ) {
bool ModuleWidget::pasteJsonAction(json_t* moduleJ) {
engine::Module::jsonStripIds(moduleJ); engine::Module::jsonStripIds(moduleJ);


json_t* oldModuleJ = toJson(); json_t* oldModuleJ = toJson();
@@ -479,7 +482,7 @@ void ModuleWidget::pasteJsonAction(json_t* moduleJ) {
catch (Exception& e) { catch (Exception& e) {
WARN("%s", e.what()); WARN("%s", e.what());
json_decref(oldModuleJ); json_decref(oldModuleJ);
return;
return false;
} }


// history::ModuleChange // history::ModuleChange
@@ -489,6 +492,7 @@ void ModuleWidget::pasteJsonAction(json_t* moduleJ) {
h->oldModuleJ = oldModuleJ; h->oldModuleJ = oldModuleJ;
h->newModuleJ = moduleJ; h->newModuleJ = moduleJ;
APP->history->push(h); APP->history->push(h);
return true;
} }


void ModuleWidget::copyClipboard() { void ModuleWidget::copyClipboard() {
@@ -501,22 +505,22 @@ void ModuleWidget::copyClipboard() {
glfwSetClipboardString(APP->window->win, json); glfwSetClipboardString(APP->window->win, json);
} }


void ModuleWidget::pasteClipboardAction() {
bool ModuleWidget::pasteClipboardAction() {
const char* json = glfwGetClipboardString(APP->window->win); const char* json = glfwGetClipboardString(APP->window->win);
if (!json) { if (!json) {
WARN("Could not get text from clipboard."); WARN("Could not get text from clipboard.");
return;
return false;
} }


json_error_t error; json_error_t error;
json_t* moduleJ = json_loads(json, 0, &error); json_t* moduleJ = json_loads(json, 0, &error);
if (!moduleJ) { if (!moduleJ) {
WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); WARN("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text);
return;
return false;
} }
DEFER({json_decref(moduleJ);}); DEFER({json_decref(moduleJ);});


pasteJsonAction(moduleJ);
return pasteJsonAction(moduleJ);
} }


void ModuleWidget::load(std::string filename) { void ModuleWidget::load(std::string filename) {
@@ -758,6 +762,9 @@ void ModuleWidget::cloneAction() {


// JSON serialization is the obvious way to do this // JSON serialization is the obvious way to do this
json_t* moduleJ = toJson(); json_t* moduleJ = toJson();
DEFER({
json_decref(moduleJ);
});
engine::Module::jsonStripIds(moduleJ); engine::Module::jsonStripIds(moduleJ);


// Clone Module // Clone Module
@@ -769,7 +776,6 @@ void ModuleWidget::cloneAction() {
catch (Exception& e) { catch (Exception& e) {
WARN("%s", e.what()); WARN("%s", e.what());
} }
json_decref(moduleJ);
APP->engine->addModule(clonedModule); APP->engine->addModule(clonedModule);


// Clone ModuleWidget // Clone ModuleWidget


+ 7
- 2
src/app/RackWidget.cpp View File

@@ -454,7 +454,7 @@ static PasteJsonReturn RackWidget_pasteJson(RackWidget* that, json_t* rootJ, his
size_t cableIndex; size_t cableIndex;
json_t* cableJ; json_t* cableJ;
json_array_foreach(cablesJ, cableIndex, cableJ) { json_array_foreach(cablesJ, cableIndex, cableJ) {
json_object_del(cableJ, "id");
engine::Cable::jsonStripIds(cableJ);


// Remap old module IDs to new IDs // Remap old module IDs to new IDs
json_t* inputModuleIdJ = json_object_get(cableJ, "inputModuleId"); json_t* inputModuleIdJ = json_object_get(cableJ, "inputModuleId");
@@ -600,6 +600,9 @@ void RackWidget::removeModule(ModuleWidget* m) {
// Disconnect cables // Disconnect cables
m->disconnect(); m->disconnect();


// Deselect module if selected
internal->selectedModules.erase(m);

// Remove module from ModuleContainer // Remove module from ModuleContainer
internal->moduleContainer->removeChild(m); internal->moduleContainer->removeChild(m);
} }
@@ -1105,7 +1108,9 @@ void RackWidget::deleteSelectionAction() {
history::ComplexAction* complexAction = new history::ComplexAction; history::ComplexAction* complexAction = new history::ComplexAction;
complexAction->name = "remove modules"; complexAction->name = "remove modules";


for (ModuleWidget* mw : getSelected()) {
// Copy selected set since removing ModuleWidgets modifies it.
std::set<ModuleWidget*> selectedModules = getSelected();
for (ModuleWidget* mw : selectedModules) {
mw->appendDisconnectActions(complexAction); mw->appendDisconnectActions(complexAction);


// history::ModuleRemove // history::ModuleRemove


+ 22
- 15
src/app/Scene.cpp View File

@@ -136,6 +136,7 @@ void Scene::onDragHover(const DragHoverEvent& e) {




void Scene::onHoverKey(const HoverKeyEvent& e) { void Scene::onHoverKey(const HoverKeyEvent& e) {
// Key commands that override children
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
// DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str()); // DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str());
if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
@@ -193,10 +194,6 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
settings::zoom = 0.f; settings::zoom = 0.f;
e.consume(this); e.consume(this);
} }
if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) {
browser->show();
e.consume(this);
}
if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) { if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) {
system::openBrowser("https://vcvrack.com/manual/"); system::openBrowser("https://vcvrack.com/manual/");
e.consume(this); e.consume(this);
@@ -211,13 +208,6 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
// menuBar->hide(); // menuBar->hide();
e.consume(this); e.consume(this);
} }
// Alternate key command for exiting fullscreen, since F11 doesn't work reliably on Mac due to "Show desktop" OS binding.
if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) {
if (APP->window->isFullScreen()) {
APP->window->setFullScreen(false);
e.consume(this);
}
}


// Module selections // Module selections
if (e.keyName == "a" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "a" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
@@ -234,10 +224,6 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this); e.consume(this);
} }
} }
if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
rack->pasteClipboardAction();
e.consume(this);
}
if (e.keyName == "i" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "i" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
if (rack->hasSelection()) { if (rack->hasSelection()) {
rack->resetSelectionAction(); rack->resetSelectionAction();
@@ -307,6 +293,27 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
if (e.isConsumed()) if (e.isConsumed())
return; return;
OpaqueWidget::onHoverKey(e); OpaqueWidget::onHoverKey(e);
if (e.isConsumed())
return;

// Key commands that can be overridden by children
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
// Alternate key command for exiting fullscreen, since F11 doesn't work reliably on Mac due to "Show desktop" OS binding.
if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) {
if (APP->window->isFullScreen()) {
APP->window->setFullScreen(false);
e.consume(this);
}
}
if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
rack->pasteClipboardAction();
e.consume(this);
}
if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) {
browser->show();
e.consume(this);
}
}
} }






+ 5
- 0
src/engine/Cable.cpp View File

@@ -60,5 +60,10 @@ void Cable::fromJson(json_t* rootJ) {
} }




void Cable::jsonStripIds(json_t* rootJ) {
json_object_del(rootJ, "id");
}


} // namespace engine } // namespace engine
} // namespace rack } // namespace rack

Loading…
Cancel
Save