@@ -112,7 +112,6 @@ struct ModuleWidget : widget::OpaqueWidget { | |||
/** Deletes `this` */ | |||
void removeAction(); | |||
void createContextMenu(); | |||
void createSelectionContextMenu(); | |||
INTERNAL math::Vec& dragOffset(); | |||
INTERNAL bool& dragEnabled(); | |||
@@ -4,6 +4,7 @@ | |||
#include <app/common.hpp> | |||
#include <widget/OpaqueWidget.hpp> | |||
#include <widget/FramebufferWidget.hpp> | |||
#include <ui/Menu.hpp> | |||
#include <app/RailWidget.hpp> | |||
#include <app/ModuleWidget.hpp> | |||
#include <app/CableWidget.hpp> | |||
@@ -70,6 +71,8 @@ struct RackWidget : widget::OpaqueWidget { | |||
void updateModuleOldPositions(); | |||
history::ComplexAction* getModuleDragAction(); | |||
// Module selection methods | |||
void updateModuleSelections(); | |||
void clearModuleSelections(); | |||
bool hasSelectedModules(); | |||
@@ -82,6 +85,7 @@ struct RackWidget : widget::OpaqueWidget { | |||
bool areSelectedModulesBypassed(); | |||
void deleteSelectedModulesAction(); | |||
bool requestSelectedModulePos(math::Vec delta); | |||
void appendSelectionContextMenu(ui::Menu* menu); | |||
// Cable methods | |||
@@ -215,6 +215,11 @@ 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); | |||
AllowCursorLockItem* allowCursorLockItem = new AllowCursorLockItem; | |||
@@ -389,7 +389,8 @@ void ModuleWidget::onButton(const ButtonEvent& e) { | |||
// Open context menu on right-click | |||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | |||
if (internal->selected) { | |||
createSelectionContextMenu(); | |||
ui::Menu* menu = createMenu(); | |||
APP->scene->rack->appendSelectionContextMenu(menu); | |||
} | |||
else { | |||
createContextMenu(); | |||
@@ -1085,47 +1086,6 @@ void ModuleWidget::createContextMenu() { | |||
appendContextMenu(menu); | |||
} | |||
void ModuleWidget::createSelectionContextMenu() { | |||
ui::Menu* menu = createMenu(); | |||
int n = APP->scene->rack->getNumSelectedModules(); | |||
menu->addChild(createMenuLabel(string::f("%d selected %s", n, n == 1 ? "module" : "modules"))); | |||
// Deselect | |||
menu->addChild(createMenuItem("Deselect", "", [=]() { | |||
APP->scene->rack->clearModuleSelections(); | |||
})); | |||
// Initialize | |||
menu->addChild(createMenuItem("Initialize", RACK_MOD_CTRL_NAME "+I", [=]() { | |||
APP->scene->rack->resetSelectedModulesAction(); | |||
})); | |||
// Randomize | |||
menu->addChild(createMenuItem("Randomize", RACK_MOD_CTRL_NAME "+R", [=]() { | |||
APP->scene->rack->randomizeSelectedModulesAction(); | |||
})); | |||
// Disconnect cables | |||
menu->addChild(createMenuItem("Disconnect cables", RACK_MOD_CTRL_NAME "+U", [=]() { | |||
APP->scene->rack->disconnectSelectedModulesAction(); | |||
})); | |||
// Bypass | |||
std::string bypassText = RACK_MOD_CTRL_NAME "+E"; | |||
bool bypassed = APP->scene->rack->areSelectedModulesBypassed(); | |||
if (bypassed) | |||
bypassText += " " CHECKMARK_STRING; | |||
menu->addChild(createMenuItem("Bypass", bypassText, [=]() { | |||
APP->scene->rack->bypassSelectedModulesAction(!bypassed); | |||
})); | |||
// Delete | |||
menu->addChild(createMenuItem("Delete", "Backspace/Delete", [=]() { | |||
APP->scene->rack->deleteSelectedModulesAction(); | |||
})); | |||
} | |||
math::Vec& ModuleWidget::dragOffset() { | |||
return internal->dragOffset; | |||
} | |||
@@ -15,6 +15,7 @@ | |||
#include <context.hpp> | |||
#include <asset.hpp> | |||
#include <patch.hpp> | |||
#include <helpers.hpp> | |||
namespace rack { | |||
@@ -828,6 +829,45 @@ bool RackWidget::requestSelectedModulePos(math::Vec delta) { | |||
return true; | |||
} | |||
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(); | |||
})); | |||
// Initialize | |||
menu->addChild(createMenuItem("Initialize", RACK_MOD_CTRL_NAME "+I", [=]() { | |||
resetSelectedModulesAction(); | |||
})); | |||
// Randomize | |||
menu->addChild(createMenuItem("Randomize", RACK_MOD_CTRL_NAME "+R", [=]() { | |||
randomizeSelectedModulesAction(); | |||
})); | |||
// Disconnect cables | |||
menu->addChild(createMenuItem("Disconnect cables", RACK_MOD_CTRL_NAME "+U", [=]() { | |||
disconnectSelectedModulesAction(); | |||
})); | |||
// Bypass | |||
std::string bypassText = RACK_MOD_CTRL_NAME "+E"; | |||
bool bypassed = areSelectedModulesBypassed(); | |||
if (bypassed) | |||
bypassText += " " CHECKMARK_STRING; | |||
menu->addChild(createMenuItem("Bypass", bypassText, [=]() { | |||
bypassSelectedModulesAction(!bypassed); | |||
})); | |||
// Delete | |||
menu->addChild(createMenuItem("Delete", "Backspace/Delete", [=]() { | |||
deleteSelectedModulesAction(); | |||
})); | |||
} | |||
void RackWidget::clearCables() { | |||
incompleteCable = NULL; | |||
internal->cableContainer->clearChildren(); | |||