Skip to content

Commit

Permalink
Leave menus up while editing fader config
Browse files Browse the repository at this point in the history
  • Loading branch information
Dewb committed Dec 30, 2024
1 parent 6b919c7 commit 5fa3676
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 29 deletions.
12 changes: 11 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@
"__node_handle": "cpp",
"mock_hardware_api_private.h": "c",
"__functional_03": "cpp",
"mutex": "cpp"
"mutex": "cpp",
"__config": "cpp",
"__hash_table": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__verbose_abort": "cpp",
"cfenv": "cpp",
"charconv": "cpp",
"execution": "cpp",
"stack": "cpp"
}
}
151 changes: 151 additions & 0 deletions src/common/widgets/CustomMenuTemplates.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#pragma once

#include "rack.hpp"
using namespace rack;

template <class TMenuItem = ui::MenuItem>
TMenuItem* createUnconsumingIndexSubmenuItem(std::string text, std::vector<std::string> labels, std::function<size_t()> getter, std::function<void(size_t val)> setter, bool disabled = false)
{
struct IndexItem : ui::MenuItem
{
std::function<size_t()> getter;
std::function<void(size_t)> setter;
size_t index;

void step() override
{
size_t currIndex = getter();
this->rightText = CHECKMARK(currIndex == index);
MenuItem::step();
}
void onAction(const event::Action& e) override
{
setter(index);
e.unconsume();
}
};

struct Item : TMenuItem
{
std::function<size_t()> getter;
std::function<void(size_t)> setter;
std::vector<std::string> labels;

void step() override
{
size_t currIndex = getter();
std::string label = (currIndex < labels.size()) ? labels[currIndex] : "";
this->rightText = label + " " + RIGHT_ARROW;
TMenuItem::step();
}
ui::Menu* createChildMenu() override
{
ui::Menu* menu = new ui::Menu;
for (size_t i = 0; i < labels.size(); i++)
{
IndexItem* item = createMenuItem<IndexItem>(labels[i]);
item->getter = getter;
item->setter = setter;
item->index = i;
menu->addChild(item);
}
return menu;
}
};

Item* item = createMenuItem<Item>(text);
item->getter = getter;
item->setter = setter;
item->labels = labels;
item->disabled = disabled;
return item;
}

template <class TMenuItem = ui::MenuItem>
TMenuItem* createUnconsumingIndexSubmenuItemWithDynamicLabels(std::string text, std::function<std::vector<std::string>()> getLabels, std::function<size_t()> getter, std::function<void(size_t val)> setter, bool disabled = false)
{
struct IndexItem : ui::MenuItem
{
std::function<size_t()> getter;
std::function<void(size_t)> setter;
size_t index;

void step() override
{
size_t currIndex = getter();
this->rightText = CHECKMARK(currIndex == index);
MenuItem::step();
}
void onAction(const event::Action& e) override
{
setter(index);
e.unconsume();
}
};

struct Item : TMenuItem
{
std::function<std::vector<std::string>()> getLabels;
std::function<size_t()> getter;
std::function<void(size_t)> setter;

void step() override
{
size_t currIndex = getter();
auto labels = getLabels();
std::string label = (currIndex < labels.size()) ? labels[currIndex] : "";
this->rightText = label + " " + RIGHT_ARROW;
TMenuItem::step();
}
ui::Menu* createChildMenu() override
{
ui::Menu* menu = new ui::Menu;
auto labels = getLabels();
for (size_t i = 0; i < labels.size(); i++)
{
IndexItem* item = createMenuItem<IndexItem>(labels[i]);
item->getter = getter;
item->setter = setter;
item->index = i;
menu->addChild(item);
}
return menu;
}
};

Item* item = createMenuItem<Item>(text);
item->getter = getter;
item->setter = setter;
item->getLabels = getLabels;
item->disabled = disabled;
return item;
}

template <class TMenuItem = ui::MenuItem>
TMenuItem* createSubmenuItemWithDynamicRightText(std::string text, std::function<std::string(void)> getRightText, std::function<void(ui::Menu* menu)> createMenu, bool disabled = false)
{
struct Item : TMenuItem
{
std::function<std::string(void)> getRightText;
std::function<void(ui::Menu* menu)> createMenu;

void step() override
{
this->rightText = getRightText() + " " + RIGHT_ARROW;
TMenuItem::step();
}

ui::Menu* createChildMenu() override
{
ui::Menu* menu = new ui::Menu;
createMenu(menu);
return menu;
}
};

Item* item = createMenuItem<Item>(text, getRightText() + " " + RIGHT_ARROW);
item->getRightText = getRightText;
item->createMenu = createMenu;
item->disabled = disabled;
return item;
}
64 changes: 36 additions & 28 deletions src/faderbank/FaderbankWidget.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "FaderbankWidget.hpp"
#include "FaderbankModule.hpp"
#include "CustomMenuTemplates.hpp"

extern rack::Plugin* pluginInstance;

Expand Down Expand Up @@ -153,10 +154,7 @@ void appendFaderConfigMenu(FaderbankModule* fb, ::Menu* menu, int faderIndex)
return;
}

FaderbankModule::ControllerRecord record = fb->records[faderIndex];

std::vector<std::string> modeNames { "CC", "CC (14-bit)" };
uint8_t ccMax = record.faderMode == FaderbankModule::FaderMode14bitCC ? 31 : 127;

std::vector<std::string> channelNames;
for (auto i = 0; i < 16; i++)
Expand All @@ -166,32 +164,28 @@ void appendFaderConfigMenu(FaderbankModule* fb, ::Menu* menu, int faderIndex)
channelNames.push_back(ss.str());
}

std::vector<std::string> ccNames;
for (auto i = 0; i < ccMax + 1; i++)
{
std::ostringstream ss;
ss << i;
ccNames.push_back(ss.str());
}

std::ostringstream faderName;
faderName << faderIndex + 1;

std::ostringstream faderDesc;
faderDesc << "Ch " << (int)(record.channel + 1) << " " << modeNames[record.faderMode] << " ";
if (record.faderMode == FaderbankModule::FaderModeCC)
{
faderDesc << (int)record.ccNum;
}
else if (record.faderMode == FaderbankModule::FaderMode14bitCC)
{
faderDesc << (int)record.ccNum << "/" << (int)(record.ccNum + 32);
}

menu->addChild(createSubmenuItem(faderName.str(), faderDesc.str(),
menu->addChild(createSubmenuItemWithDynamicRightText(faderName.str(),
[=]()
{
FaderbankModule::ControllerRecord record = fb->records[faderIndex];
std::ostringstream faderDesc;
faderDesc << "Ch " << (int)(record.channel + 1) << " " << modeNames[record.faderMode] << " ";
if (record.faderMode == FaderbankModule::FaderModeCC)
{
faderDesc << (int)record.ccNum;
}
else if (record.faderMode == FaderbankModule::FaderMode14bitCC)
{
faderDesc << (int)record.ccNum << "/" << (int)(record.ccNum + 32);
}
return faderDesc.str();
},
[=](Menu* childMenu)
{
childMenu->addChild(createIndexSubmenuItem("Channel", channelNames,
childMenu->addChild(createUnconsumingIndexSubmenuItem("Channel", channelNames,
[=]()
{
return fb->records[faderIndex].channel;
Expand All @@ -203,7 +197,7 @@ void appendFaderConfigMenu(FaderbankModule* fb, ::Menu* menu, int faderIndex)
}
));

childMenu->addChild(createIndexSubmenuItem("Mode", modeNames,
childMenu->addChild(createUnconsumingIndexSubmenuItem("Mode", modeNames,
[=]()
{
return fb->records[faderIndex].faderMode;
Expand All @@ -215,7 +209,21 @@ void appendFaderConfigMenu(FaderbankModule* fb, ::Menu* menu, int faderIndex)
}
));

childMenu->addChild(createIndexSubmenuItem("CC Number", ccNames,
childMenu->addChild(createUnconsumingIndexSubmenuItemWithDynamicLabels("CC Number",
[=]()
{
FaderbankModule::ControllerRecord record = fb->records[faderIndex];
uint8_t ccMax = record.faderMode == FaderbankModule::FaderMode14bitCC ? 31 : 127;

std::vector<std::string> ccNames;
for (auto i = 0; i < ccMax + 1; i++)
{
std::ostringstream ss;
ss << i;
ccNames.push_back(ss.str());
}
return ccNames;
},
[=]()
{
return fb->records[faderIndex].ccNum;
Expand All @@ -240,7 +248,7 @@ void FaderbankWidget::appendContextMenu(Menu* menu)

menu->addChild(new MenuSeparator());

menu->addChild(createIndexSubmenuItem("Fader voltage range", { "0-10V", "0-5V", "+/-5V" },
menu->addChild(createUnconsumingIndexSubmenuItem("Fader voltage range", { "0-10V", "0-5V", "+/-5V" },
[=]() {
return fb->faderRange;
},
Expand All @@ -256,7 +264,7 @@ void FaderbankWidget::appendContextMenu(Menu* menu)
}
}));

menu->addChild(createIndexSubmenuItem("Fader size", { "90mm", "60mm" },
menu->addChild(createUnconsumingIndexSubmenuItem("Fader size", { "90mm", "60mm" },
[=]() {
return fb->faderSize;
},
Expand Down

0 comments on commit 5fa3676

Please sign in to comment.