#pragma once #include #include "SynthParams.h" class MenuSystem; struct MenuItem { enum Kind { Action, Value, Submenu, Separator }; juce::String label; Kind kind = Action; int paramId = -1; std::function onEnter; std::function onAdjust; std::function valueText; MenuItem& action (std::function fn) { onEnter = fn; return *this; } MenuItem& param (int id, float lo, float hi) { paramId = id; return *this; } MenuItem& value (std::function fn) { valueText = fn; kind = Value; return *this; } MenuItem& submenu() { kind = Submenu; return *this; } MenuItem& sep() { kind = Separator; return *this; } }; struct MenuScreen { juce::String title; std::vector items; int selected = 0; }; class MenuSystem { public: MenuSystem(); void open(); void close(); bool isOpen() const { return ! stack.empty(); } void up(); void down(); void left(); void right(); void enter(); void escape(); const MenuScreen& current() const; void pushScreen (const MenuScreen& screen); using ScreenBuilder = std::function; void setRootScreenBuilder (ScreenBuilder fn); void refreshCurrent(); private: std::vector stack; ScreenBuilder rootBuilder; bool wasOpen = false; void rebuildRoot(); };