| @@ -1 +1 @@ | |||
| Subproject commit eafa8349a9dd745a3739a78166606801c17240d2 | |||
| Subproject commit d0a26d6d205ce51c450806d615c8edd3e48e7a90 | |||
| @@ -21,9 +21,10 @@ | |||
| #define DISTRHO_PLUGIN_NAME "Parameters" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Parameters" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -28,7 +28,7 @@ class ExamplePluginParameters : public Plugin | |||
| { | |||
| public: | |||
| ExamplePluginParameters() | |||
| : Plugin(9, 0, 0) // 9 parameters, 0 programs, 0 states | |||
| : Plugin(9, 2, 0) // 9 parameters, 2 programs, 0 states | |||
| { | |||
| /** | |||
| Initialize all our parameters to their defaults. | |||
| @@ -117,7 +117,7 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| /** | |||
| Changing parameters does not cause any realtime-unsafe operations, so we can mark them as automable. | |||
| Also set as boolean because they work are on/off switches. | |||
| Also set as boolean because they work as on/off switches. | |||
| */ | |||
| parameter.hints = kParameterIsAutomable|kParameterIsBoolean; | |||
| @@ -171,6 +171,23 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| parameter.symbol.replace('-', '_'); | |||
| } | |||
| /** | |||
| Set the name of the program @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initProgramName(uint32_t index, String& programName) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| programName = "Default"; | |||
| break; | |||
| case 1: | |||
| programName = "Custom"; | |||
| break; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| @@ -190,6 +207,39 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| fParamGrid[index] = value; | |||
| } | |||
| /** | |||
| Load a program. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| void loadProgram(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = 0.0f; | |||
| fParamGrid[1] = 0.0f; | |||
| fParamGrid[2] = 0.0f; | |||
| fParamGrid[3] = 0.0f; | |||
| fParamGrid[4] = 0.0f; | |||
| fParamGrid[5] = 0.0f; | |||
| fParamGrid[6] = 0.0f; | |||
| fParamGrid[7] = 0.0f; | |||
| fParamGrid[8] = 0.0f; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = 1.0f; | |||
| fParamGrid[1] = 1.0f; | |||
| fParamGrid[2] = 0.0f; | |||
| fParamGrid[3] = 0.0f; | |||
| fParamGrid[4] = 1.0f; | |||
| fParamGrid[5] = 1.0f; | |||
| fParamGrid[6] = 1.0f; | |||
| fParamGrid[7] = 0.0f; | |||
| fParamGrid[8] = 1.0f; | |||
| break; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Process */ | |||
| @@ -18,12 +18,6 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /** | |||
| We need the rectangle class from DGL. | |||
| */ | |||
| @@ -34,6 +28,13 @@ using DGL::Rectangle; | |||
| class ExampleUIParameters : public UI | |||
| { | |||
| public: | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /* constructor */ | |||
| ExampleUIParameters() | |||
| : UI(kUIWidth, kUIHeight) | |||
| { | |||
| @@ -61,6 +62,40 @@ protected: | |||
| repaint(); | |||
| } | |||
| /** | |||
| A program has been loaded on the plugin side. | |||
| This is called by the host to inform the UI about program changes. | |||
| */ | |||
| void programLoaded(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| repaint(); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Widget Callbacks */ | |||
| @@ -21,11 +21,11 @@ | |||
| #define DISTRHO_PLUGIN_NAME "States" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/States" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_STATE 1 | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
| #define DISTRHO_PLUGIN_WANT_STATE 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -28,9 +28,13 @@ class ExamplePluginStates : public Plugin | |||
| { | |||
| public: | |||
| ExamplePluginStates() | |||
| : Plugin(0, 0, 9) // 0 parameters, 0 programs, 9 states | |||
| : Plugin(0, 2, 9) // 0 parameters, 2 programs, 9 states | |||
| { | |||
| // nothing here | |||
| /** | |||
| Initialize all our parameters to their defaults. | |||
| In this example all default values are false, so we can simply zero them. | |||
| */ | |||
| std::memset(fParamGrid, 0, sizeof(bool)*9); | |||
| } | |||
| protected: | |||
| @@ -98,17 +102,29 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Parameters */ | |||
| * Init */ | |||
| /** | |||
| This plugin has no parameters, so we can safely ignore some functions. | |||
| This plugin has no parameters.. | |||
| */ | |||
| void initParameter(uint32_t, Parameter&) override {} | |||
| void setParameterValue(uint32_t, float) override {} | |||
| float getParameterValue(uint32_t) const override { return 0.0f; } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * State */ | |||
| /** | |||
| Set the name of the program @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initProgramName(uint32_t index, String& programName) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| programName = "Default"; | |||
| break; | |||
| case 1: | |||
| programName = "Custom"; | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| Set the state key and default value of @a index. | |||
| @@ -150,13 +166,106 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| defaultStateValue = "false"; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| This plugin has no parameters.. | |||
| */ | |||
| void setParameterValue(uint32_t, float) override {} | |||
| float getParameterValue(uint32_t) const override { return 0.0f; } | |||
| /** | |||
| Load a program. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| void loadProgram(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| Get the value of an internal state. | |||
| The host may call this function from any non-realtime context. | |||
| */ | |||
| String getState(const char* key) const override | |||
| { | |||
| static const String sTrue ("true"); | |||
| static const String sFalse("false"); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| return fParamGrid[0] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| return fParamGrid[1] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| return fParamGrid[2] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| return fParamGrid[3] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| return fParamGrid[4] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| return fParamGrid[5] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| return fParamGrid[6] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| return fParamGrid[7] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| return fParamGrid[8] ? sTrue : sFalse; | |||
| return sFalse; | |||
| } | |||
| /** | |||
| Change an internal state. | |||
| */ | |||
| void setState(const char*, const char*) override | |||
| void setState(const char* key, const char* value) override | |||
| { | |||
| // there is no plugin side state here. | |||
| // states on this plugin will only change the UI grid, so we do nothing here | |||
| const bool valueOnOff = (std::strcmp(value, "true") == 0); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| fParamGrid[0] = valueOnOff; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| fParamGrid[1] = valueOnOff; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| fParamGrid[2] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| fParamGrid[3] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| fParamGrid[4] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| fParamGrid[5] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| fParamGrid[6] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| fParamGrid[7] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| fParamGrid[8] = valueOnOff; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| @@ -182,7 +291,11 @@ The plugin will be treated as an effect, but it will not change the host audio." | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| // nothing here | |||
| /** | |||
| Our parameters used to display the grid on/off states. | |||
| */ | |||
| bool fParamGrid[9]; | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| @@ -18,43 +18,39 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /** | |||
| We need the rectangle class from DGL. | |||
| */ | |||
| using DGL::Rectangle; | |||
| /** | |||
| Get key name from an index. | |||
| */ | |||
| static const char* getStateKeyFromIndex(const uint32_t index) | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: return "top-left"; | |||
| case 1: return "top-center"; | |||
| case 2: return "top-right"; | |||
| case 3: return "middle-left"; | |||
| case 4: return "middle-center"; | |||
| case 5: return "middle-right"; | |||
| case 6: return "bottom-left"; | |||
| case 7: return "bottom-center"; | |||
| case 8: return "bottom-right"; | |||
| } | |||
| return "unknown"; | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| class ExampleUIParameters : public UI | |||
| { | |||
| public: | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /** | |||
| Get key name from an index. | |||
| */ | |||
| static const char* getStateKeyFromIndex(const uint32_t index) noexcept | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: return "top-left"; | |||
| case 1: return "top-center"; | |||
| case 2: return "top-right"; | |||
| case 3: return "middle-left"; | |||
| case 4: return "middle-center"; | |||
| case 5: return "middle-right"; | |||
| case 6: return "bottom-left"; | |||
| case 7: return "bottom-center"; | |||
| case 8: return "bottom-right"; | |||
| } | |||
| return "unknown"; | |||
| } | |||
| /* constructor */ | |||
| ExampleUIParameters() | |||
| : UI() | |||
| { | |||
| @@ -75,32 +71,69 @@ protected: | |||
| */ | |||
| void parameterChanged(uint32_t, float) override {} | |||
| /** | |||
| A program has been loaded on the plugin side. | |||
| This is called by the host to inform the UI about program changes. | |||
| */ | |||
| void programLoaded(uint32_t index) override | |||
| { | |||
| d_stdout("UI programLoaded %i", index); | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| repaint(); | |||
| } | |||
| /** | |||
| A state has changed on the plugin side. | |||
| This is called by the host to inform the UI about state changes. | |||
| */ | |||
| void stateChanged(const char* key, const char* value) | |||
| void stateChanged(const char* key, const char* value) override | |||
| { | |||
| // check which block changed, enable it if its value is "true" | |||
| const bool valueOnOff = (std::strcmp(value, "true") == 0); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| fParamGrid[0] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[0] = valueOnOff; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| fParamGrid[1] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[1] = valueOnOff; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| fParamGrid[2] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[2] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| fParamGrid[3] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[3] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| fParamGrid[4] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[4] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| fParamGrid[5] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[5] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| fParamGrid[6] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[6] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| fParamGrid[7] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[7] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| fParamGrid[8] = (std::strcmp(value, "true") == 0); | |||
| fParamGrid[8] = valueOnOff; | |||
| // trigger repaint | |||
| repaint(); | |||