diff --git a/include/app/RackWidget.hpp b/include/app/RackWidget.hpp index cd6780c8..8fe5b98f 100644 --- a/include/app/RackWidget.hpp +++ b/include/app/RackWidget.hpp @@ -74,7 +74,8 @@ struct RackWidget : widget::OpaqueWidget { // Module selection methods void updateModuleSelections(); - void clearModuleSelections(); + void deselectModules(); + void selectAllModules(); bool hasSelectedModules(); int getNumSelectedModules(); std::list getSelectedModules(); diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index f402747a..5cf11a14 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -215,10 +215,8 @@ struct EditButton : MenuButton { disconnectCablesItem->text = "Clear cables"; menu->addChild(disconnectCablesItem); - if (APP->scene->rack->hasSelectedModules()) { - menu->addChild(new ui::MenuSeparator); - APP->scene->rack->appendSelectionContextMenu(menu); - } + menu->addChild(new ui::MenuSeparator); + APP->scene->rack->appendSelectionContextMenu(menu); menu->addChild(new ui::MenuSeparator); diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index c4a732f2..668c5d6d 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -654,12 +654,18 @@ void RackWidget::updateModuleSelections() { } } -void RackWidget::clearModuleSelections() { +void RackWidget::deselectModules() { for (ModuleWidget* mw : getModules()) { mw->selected() = false; } } +void RackWidget::selectAllModules() { + for (ModuleWidget* mw : getModules()) { + mw->selected() = true; + } +} + bool RackWidget::hasSelectedModules() { for (widget::Widget* w : internal->moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); @@ -833,39 +839,44 @@ void RackWidget::appendSelectionContextMenu(ui::Menu* menu) { int n = getNumSelectedModules(); menu->addChild(createMenuLabel(string::f("%d selected %s", n, n == 1 ? "module" : "modules"))); - // Deselect - menu->addChild(createMenuItem("Deselect", "", [=]() { - clearModuleSelections(); + // Select all + menu->addChild(createMenuItem("Select all", RACK_MOD_CTRL_NAME "+A", [=]() { + selectAllModules(); })); + // Deselect + menu->addChild(createMenuItem("Deselect", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+A", [=]() { + deselectModules(); + }, n == 0)); + // Initialize menu->addChild(createMenuItem("Initialize", RACK_MOD_CTRL_NAME "+I", [=]() { resetSelectedModulesAction(); - })); + }, n == 0)); // Randomize menu->addChild(createMenuItem("Randomize", RACK_MOD_CTRL_NAME "+R", [=]() { randomizeSelectedModulesAction(); - })); + }, n == 0)); // Disconnect cables menu->addChild(createMenuItem("Disconnect cables", RACK_MOD_CTRL_NAME "+U", [=]() { disconnectSelectedModulesAction(); - })); + }, n == 0)); // Bypass std::string bypassText = RACK_MOD_CTRL_NAME "+E"; - bool bypassed = areSelectedModulesBypassed(); + bool bypassed = (n > 0) && areSelectedModulesBypassed(); if (bypassed) bypassText += " " CHECKMARK_STRING; menu->addChild(createMenuItem("Bypass", bypassText, [=]() { bypassSelectedModulesAction(!bypassed); - })); + }, n == 0)); // Delete menu->addChild(createMenuItem("Delete", "Backspace/Delete", [=]() { deleteSelectedModulesAction(); - })); + }, n == 0)); } void RackWidget::clearCables() { diff --git a/src/app/Scene.cpp b/src/app/Scene.cpp index 29220da0..3f5b003c 100644 --- a/src/app/Scene.cpp +++ b/src/app/Scene.cpp @@ -212,6 +212,14 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { } // Module selections + if (e.keyName == "a" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { + rack->selectAllModules(); + e.consume(this); + } + if (e.keyName == "a" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { + rack->deselectModules(); + e.consume(this); + } if (e.keyName == "i" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (rack->hasSelectedModules()) rack->resetSelectedModulesAction();