| @@ -82,6 +82,7 @@ struct RackWidget : widget::OpaqueWidget { | |||||
| void resetSelectedModulesAction(); | void resetSelectedModulesAction(); | ||||
| void randomizeSelectedModulesAction(); | void randomizeSelectedModulesAction(); | ||||
| void disconnectSelectedModulesAction(); | void disconnectSelectedModulesAction(); | ||||
| void cloneSelectedModulesAction(); | |||||
| void bypassSelectedModulesAction(bool bypassed); | void bypassSelectedModulesAction(bool bypassed); | ||||
| bool areSelectedModulesBypassed(); | bool areSelectedModulesBypassed(); | ||||
| void deleteSelectedModulesAction(); | void deleteSelectedModulesAction(); | ||||
| @@ -345,8 +345,10 @@ void ModuleWidget::onHoverKey(const HoverKeyEvent& e) { | |||||
| e.consume(this); | 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(); | |||||
| e.consume(this); | |||||
| if (!APP->scene->rack->hasSelectedModules()) { | |||||
| cloneAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } | } | ||||
| if (e.keyName == "u" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | if (e.keyName == "u" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | ||||
| if (!APP->scene->rack->hasSelectedModules()) { | if (!APP->scene->rack->hasSelectedModules()) { | ||||
| @@ -761,6 +761,10 @@ void RackWidget::disconnectSelectedModulesAction() { | |||||
| delete complexAction; | delete complexAction; | ||||
| } | } | ||||
| void RackWidget::cloneSelectedModulesAction() { | |||||
| // TODO | |||||
| } | |||||
| void RackWidget::bypassSelectedModulesAction(bool bypassed) { | void RackWidget::bypassSelectedModulesAction(bool bypassed) { | ||||
| history::ComplexAction* complexAction = new history::ComplexAction; | history::ComplexAction* complexAction = new history::ComplexAction; | ||||
| complexAction->name = bypassed ? "bypass modules" : "un-bypass modules"; | complexAction->name = bypassed ? "bypass modules" : "un-bypass modules"; | ||||
| @@ -877,6 +881,11 @@ void RackWidget::appendSelectionContextMenu(ui::Menu* menu) { | |||||
| disconnectSelectedModulesAction(); | disconnectSelectedModulesAction(); | ||||
| }, n == 0)); | }, n == 0)); | ||||
| // Duplicate | |||||
| menu->addChild(createMenuItem("Duplicate", RACK_MOD_CTRL_NAME "+D", [=]() { | |||||
| cloneSelectedModulesAction(); | |||||
| })); | |||||
| // Bypass | // Bypass | ||||
| std::string bypassText = RACK_MOD_CTRL_NAME "+E"; | std::string bypassText = RACK_MOD_CTRL_NAME "+E"; | ||||
| bool bypassed = (n > 0) && areSelectedModulesBypassed(); | bool bypassed = (n > 0) && areSelectedModulesBypassed(); | ||||
| @@ -230,6 +230,11 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { | |||||
| rack->randomizeSelectedModulesAction(); | rack->randomizeSelectedModulesAction(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| if (e.keyName == "d" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (rack->hasSelectedModules()) | |||||
| rack->cloneSelectedModulesAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "u" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | if (e.keyName == "u" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | ||||
| if (rack->hasSelectedModules()) | if (rack->hasSelectedModules()) | ||||
| rack->disconnectSelectedModulesAction(); | rack->disconnectSelectedModulesAction(); | ||||