#pragma once #include #include #include #include namespace effector { // Declarative description of one effect knob. The GUI turns these into widgets // and the CLI turns them into flags, so neither knows about any effect. struct ParamSpec { enum class Type { Int, Double, Bool, Choice, Path }; Type type = Type::Int; std::string key; std::string label; std::string help; double defaultValue = 0.0; double minimum = 0.0; double maximum = 0.0; double step = 1.0; int digits = 2; std::string defaultChoice; std::vector choices; std::string flag() const; // "strip_height" -> "--strip-height" static ParamSpec makeInt(std::string key, std::string label, long defaultValue, long minimum, long maximum, std::string help = {}, long step = 1); static ParamSpec makeDouble(std::string key, std::string label, double defaultValue, double minimum, double maximum, std::string help = {}, double step = 0.05, int digits = 2); static ParamSpec makeBool(std::string key, std::string label, bool defaultValue, std::string help = {}); static ParamSpec makeChoice(std::string key, std::string label, std::string defaultChoice, std::vector choices, std::string help = {}); // A path to a file on disk, empty by default: a chooser in the interface, a // flag taking any string on the command line, written relative to the // project folder so that a folder still opens after it is moved. static ParamSpec makePath(std::string key, std::string label, std::string help = {}); }; using ParamValue = std::variant; using ParamValues = std::map; long paramInt(const ParamValues& values, const std::string& key, long fallback); double paramDouble(const ParamValues& values, const std::string& key, double fallback); bool paramBool(const ParamValues& values, const std::string& key, bool fallback); std::string paramChoice(const ParamValues& values, const std::string& key, const std::string& fallback); std::string paramText(const ParamValues& values, const std::string& key, const std::string& fallback); } // namespace effector