SM-26 synthesizer: initial implementation

This commit is contained in:
SM-26 2026-09-11 16:38:28 +02:00
commit 8734ac25f1
18 changed files with 2619 additions and 0 deletions

124
Source/MenuSystem.cpp Normal file
View file

@ -0,0 +1,124 @@
#include "MenuSystem.h"
MenuSystem::MenuSystem() {}
void MenuSystem::setRootScreenBuilder (ScreenBuilder fn) { rootBuilder = fn; }
void MenuSystem::rebuildRoot()
{
if (rootBuilder)
{
MenuScreen root = rootBuilder();
stack.clear();
stack.push_back (root);
}
}
void MenuSystem::open()
{
wasOpen = true;
rebuildRoot();
}
void MenuSystem::close()
{
stack.clear();
wasOpen = false;
}
void MenuSystem::pushScreen (const MenuScreen& screen) { stack.push_back (screen); }
const MenuScreen& MenuSystem::current() const
{
if (stack.empty())
{
static MenuScreen empty;
empty.title = "";
empty.selected = 0;
return empty;
}
return stack.back();
}
void MenuSystem::refreshCurrent()
{
if (! stack.empty())
{
int sel = stack.back().selected;
stack.pop_back();
if (stack.empty() && rootBuilder)
{
MenuScreen root = rootBuilder();
root.selected = sel;
stack.push_back (root);
}
else if (! stack.empty())
{
stack.back().selected = sel;
}
}
}
void MenuSystem::up()
{
if (stack.empty()) return;
auto& s = stack.back();
if (s.items.empty()) return;
int newSel = s.selected - 1;
while (newSel >= 0 && s.items[(size_t) newSel].kind == MenuItem::Separator)
--newSel;
if (newSel >= 0)
s.selected = newSel;
}
void MenuSystem::down()
{
if (stack.empty()) return;
auto& s = stack.back();
if (s.items.empty()) return;
int newSel = s.selected + 1;
while (newSel < (int) s.items.size() && s.items[(size_t) newSel].kind == MenuItem::Separator)
++newSel;
if (newSel < (int) s.items.size())
s.selected = newSel;
}
void MenuSystem::left()
{
if (stack.empty()) return;
auto& s = stack.back();
if (s.items.empty()) return;
auto& item = s.items[(size_t) s.selected];
if (item.kind == MenuItem::Value && item.onAdjust)
item.onAdjust (-0.02f);
}
void MenuSystem::right()
{
if (stack.empty()) return;
auto& s = stack.back();
if (s.items.empty()) return;
auto& item = s.items[(size_t) s.selected];
if (item.kind == MenuItem::Value && item.onAdjust)
item.onAdjust (0.02f);
}
void MenuSystem::enter()
{
if (stack.empty()) return;
auto& s = stack.back();
if (s.items.empty()) return;
auto& item = s.items[(size_t) s.selected];
if (item.onEnter)
item.onEnter();
}
void MenuSystem::escape()
{
if (stack.size() > 1)
stack.pop_back();
else if (stack.size() == 1)
close();
}