Initial attempt at plugin state/restore
This commit is contained in:
parent
8b52d9a80e
commit
b5785743e8
6 changed files with 370 additions and 81 deletions
|
|
@ -32,7 +32,8 @@
|
||||||
#include <osdialog.h>
|
#include <osdialog.h>
|
||||||
|
|
||||||
#include "PluginContext.hpp"
|
#include "PluginContext.hpp"
|
||||||
#include "extra/Mutex.hpp"
|
#include "WindowParameters.hpp"
|
||||||
|
#include "extra/Base64.hpp"
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace plugin {
|
namespace plugin {
|
||||||
|
|
@ -128,8 +129,13 @@ class CardinalPlugin : public CardinalBasePlugin
|
||||||
rack::audio::Device* fCurrentDevice;
|
rack::audio::Device* fCurrentDevice;
|
||||||
Mutex fDeviceMutex;
|
Mutex fDeviceMutex;
|
||||||
|
|
||||||
|
float fParameters[kWindowParameterCount];
|
||||||
|
|
||||||
struct ScopedContext {
|
struct ScopedContext {
|
||||||
ScopedContext(CardinalPlugin* const plugin)
|
const MutexLocker cml;
|
||||||
|
|
||||||
|
ScopedContext(const CardinalPlugin* const plugin)
|
||||||
|
: cml(plugin->contextMutex)
|
||||||
{
|
{
|
||||||
rack::contextSet(plugin->fContext);
|
rack::contextSet(plugin->fContext);
|
||||||
}
|
}
|
||||||
|
|
@ -142,13 +148,18 @@ class CardinalPlugin : public CardinalBasePlugin
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CardinalPlugin()
|
CardinalPlugin()
|
||||||
: CardinalBasePlugin(0, 0, 0),
|
: CardinalBasePlugin(kWindowParameterCount, 0, 1),
|
||||||
fContext(new CardinalPluginContext(this)),
|
fContext(new CardinalPluginContext(this)),
|
||||||
fAudioBufferIn(nullptr),
|
fAudioBufferIn(nullptr),
|
||||||
fAudioBufferOut(nullptr),
|
fAudioBufferOut(nullptr),
|
||||||
fIsActive(false),
|
fIsActive(false),
|
||||||
fCurrentDevice(nullptr)
|
fCurrentDevice(nullptr)
|
||||||
{
|
{
|
||||||
|
fParameters[kWindowParameterCableOpacity] = 50.0f;
|
||||||
|
fParameters[kWindowParameterCableTension] = 50.0f;
|
||||||
|
fParameters[kWindowParameterRackBrightness] = 100.0f;
|
||||||
|
fParameters[kWindowParameterHaloBrightness] = 25.0f;
|
||||||
|
|
||||||
// create unique temporary path for this instance
|
// create unique temporary path for this instance
|
||||||
try {
|
try {
|
||||||
char uidBuf[24];
|
char uidBuf[24];
|
||||||
|
|
@ -232,60 +243,38 @@ protected:
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* Information */
|
* Information */
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin label.
|
|
||||||
A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
|
|
||||||
*/
|
|
||||||
const char* getLabel() const override
|
const char* getLabel() const override
|
||||||
{
|
{
|
||||||
return "Cardinal";
|
return "Cardinal";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get an extensive comment/description about the plugin.
|
|
||||||
*/
|
|
||||||
const char* getDescription() const override
|
const char* getDescription() const override
|
||||||
{
|
{
|
||||||
return "...";
|
return ""
|
||||||
|
"Cardinal is an open-source self-contained special plugin version of VCVRack, using DPF.\n"
|
||||||
|
"It is NOT an official VCV project, and it is not affiliated with it in any way.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin author/maker.
|
|
||||||
*/
|
|
||||||
const char* getMaker() const override
|
const char* getMaker() const override
|
||||||
{
|
{
|
||||||
return "DISTRHO";
|
return "DISTRHO";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin homepage.
|
|
||||||
*/
|
|
||||||
const char* getHomePage() const override
|
const char* getHomePage() const override
|
||||||
{
|
{
|
||||||
return "https://github.com/DISTRHO/Cardinal";
|
return "https://github.com/DISTRHO/Cardinal";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin license name (a single line of text).
|
|
||||||
For commercial plugins this should return some short copyright information.
|
|
||||||
*/
|
|
||||||
const char* getLicense() const override
|
const char* getLicense() const override
|
||||||
{
|
{
|
||||||
return "ISC";
|
return "GPLv3+";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin version, in hexadecimal.
|
|
||||||
*/
|
|
||||||
uint32_t getVersion() const override
|
uint32_t getVersion() const override
|
||||||
{
|
{
|
||||||
return d_version(1, 0, 0);
|
return d_version(2, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Get the plugin unique Id.
|
|
||||||
This value is used by LADSPA, DSSI and VST plugin formats.
|
|
||||||
*/
|
|
||||||
int64_t getUniqueId() const override
|
int64_t getUniqueId() const override
|
||||||
{
|
{
|
||||||
return d_cconst('d', 'C', 'd', 'n');
|
return d_cconst('d', 'C', 'd', 'n');
|
||||||
|
|
@ -294,9 +283,110 @@ protected:
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* Init */
|
* Init */
|
||||||
|
|
||||||
|
void initParameter(const uint32_t index, Parameter& parameter) override
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case kWindowParameterCableOpacity:
|
||||||
|
parameter.name = "Cable Opacity";
|
||||||
|
parameter.symbol = "cableOpacity";
|
||||||
|
parameter.unit = "%";
|
||||||
|
parameter.hints = kParameterIsAutomable;
|
||||||
|
parameter.ranges.def = 50.0f;
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterCableTension:
|
||||||
|
parameter.name = "Cable Tension";
|
||||||
|
parameter.symbol = "cableTension";
|
||||||
|
parameter.unit = "%";
|
||||||
|
parameter.hints = kParameterIsAutomable;
|
||||||
|
parameter.ranges.def = 50.0f;
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterRackBrightness:
|
||||||
|
parameter.name = "Rack Brightness";
|
||||||
|
parameter.symbol = "rackBrightness";
|
||||||
|
parameter.unit = "%";
|
||||||
|
parameter.hints = kParameterIsAutomable;
|
||||||
|
parameter.ranges.def = 100.0f;
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterHaloBrightness:
|
||||||
|
parameter.name = "Halo Brightness";
|
||||||
|
parameter.symbol = "haloBrightness";
|
||||||
|
parameter.unit = "%";
|
||||||
|
parameter.hints = kParameterIsAutomable;
|
||||||
|
parameter.ranges.def = 25.0f;
|
||||||
|
parameter.ranges.min = 0.0f;
|
||||||
|
parameter.ranges.max = 100.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initState(const uint32_t index, String& stateKey, String& defaultStateValue) override
|
||||||
|
{
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(index == 0,);
|
||||||
|
|
||||||
|
stateKey = "patch";
|
||||||
|
defaultStateValue = "";
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* Internal data */
|
* Internal data */
|
||||||
|
|
||||||
|
float getParameterValue(const uint32_t index) const override
|
||||||
|
{
|
||||||
|
return fParameters[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParameterValue(const uint32_t index, float value) override
|
||||||
|
{
|
||||||
|
fParameters[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getState(const char* const key) const override
|
||||||
|
{
|
||||||
|
if (std::strcmp(key, "patch") != 0)
|
||||||
|
return String();
|
||||||
|
if (fAutosavePath.empty())
|
||||||
|
return String();
|
||||||
|
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
|
||||||
|
{
|
||||||
|
const ScopedContext sc(this);
|
||||||
|
|
||||||
|
fContext->engine->prepareSave();
|
||||||
|
fContext->patch->saveAutosave();
|
||||||
|
fContext->patch->cleanAutosave();
|
||||||
|
|
||||||
|
data = rack::system::archiveDirectory(fAutosavePath, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String::asBase64(data.data(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setState(const char* const key, const char* const value) override
|
||||||
|
{
|
||||||
|
if (std::strcmp(key, "patch") != 0)
|
||||||
|
return;
|
||||||
|
if (fAutosavePath.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const std::vector<uint8_t> data(d_getChunkFromBase64String(value));
|
||||||
|
|
||||||
|
const ScopedContext sc(this);
|
||||||
|
|
||||||
|
rack::system::removeRecursively(fAutosavePath);
|
||||||
|
rack::system::createDirectories(fAutosavePath);
|
||||||
|
rack::system::unarchiveToDirectory(data, fAutosavePath);
|
||||||
|
|
||||||
|
fContext->patch->loadAutosave();
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* Process */
|
* Process */
|
||||||
|
|
||||||
|
|
@ -329,9 +419,6 @@ protected:
|
||||||
fAudioBufferIn = fAudioBufferOut = nullptr;
|
fAudioBufferIn = fAudioBufferOut = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Run/process function for plugins without MIDI input.
|
|
||||||
*/
|
|
||||||
void run(const float** const inputs, float** const outputs, const uint32_t frames) override
|
void run(const float** const inputs, float** const outputs, const uint32_t frames) override
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -340,8 +427,9 @@ protected:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const MutexLocker cml(fDeviceMutex);
|
const MutexLocker cml(fDeviceMutex);
|
||||||
|
// const MutexTryLocker cmtl(fPatchMutex);
|
||||||
|
|
||||||
if (fCurrentDevice == nullptr)
|
if (fCurrentDevice == nullptr /*|| cmtl.wasNotLocked()*/)
|
||||||
{
|
{
|
||||||
std::memset(outputs[0], 0, sizeof(float)*frames);
|
std::memset(outputs[0], 0, sizeof(float)*frames);
|
||||||
std::memset(outputs[1], 0, sizeof(float)*frames);
|
std::memset(outputs[1], 0, sizeof(float)*frames);
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,13 @@
|
||||||
#include <ui/MenuItem.hpp>
|
#include <ui/MenuItem.hpp>
|
||||||
#include <window/Window.hpp>
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
#include "PluginContext.hpp"
|
#ifdef NDEBUG
|
||||||
|
# undef DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "DistrhoUI.hpp"
|
#include "DistrhoUI.hpp"
|
||||||
|
#include "PluginContext.hpp"
|
||||||
|
#include "WindowParameters.hpp"
|
||||||
#include "ResizeHandle.hpp"
|
#include "ResizeHandle.hpp"
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window) { return nullptr; }
|
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window) { return nullptr; }
|
||||||
|
|
@ -45,20 +49,29 @@ START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
CardinalPluginContext* getRackContextFromPlugin(void* ptr);
|
CardinalPluginContext* getRackContextFromPlugin(void* ptr);
|
||||||
|
|
||||||
class CardinalUI : public UI
|
class CardinalUI : public UI,
|
||||||
|
public WindowParametersCallback
|
||||||
{
|
{
|
||||||
CardinalPluginContext* const fContext;
|
CardinalPluginContext* const fContext;
|
||||||
rack::math::Vec fLastMousePos;
|
rack::math::Vec fLastMousePos;
|
||||||
ResizeHandle fResizeHandle;
|
ResizeHandle fResizeHandle;
|
||||||
|
WindowParameters fWindowParameters;
|
||||||
|
|
||||||
struct ScopedContext {
|
struct ScopedContext {
|
||||||
|
CardinalPluginContext* const context;
|
||||||
|
const MutexLocker cml;
|
||||||
|
|
||||||
ScopedContext(CardinalUI* const ui)
|
ScopedContext(CardinalUI* const ui)
|
||||||
|
: context(ui->fContext),
|
||||||
|
cml(context->plugin->contextMutex)
|
||||||
{
|
{
|
||||||
rack::contextSet(ui->fContext);
|
rack::contextSet(context);
|
||||||
|
WindowParametersRestore(context->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopedContext()
|
~ScopedContext()
|
||||||
{
|
{
|
||||||
|
WindowParametersSave(context->window);
|
||||||
rack::contextSet(nullptr);
|
rack::contextSet(nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -72,58 +85,63 @@ public:
|
||||||
if (isResizable())
|
if (isResizable())
|
||||||
fResizeHandle.hide();
|
fResizeHandle.hide();
|
||||||
|
|
||||||
const ScopedContext sc(this);
|
|
||||||
|
|
||||||
fContext->event = new rack::widget::EventState;
|
|
||||||
fContext->scene = new rack::app::Scene;
|
|
||||||
fContext->event->rootWidget = fContext->scene;
|
|
||||||
|
|
||||||
fContext->window = new rack::window::Window;
|
fContext->window = new rack::window::Window;
|
||||||
rack::window::WindowInit(fContext->window, this);
|
|
||||||
|
|
||||||
// Hide non-wanted menu entries
|
|
||||||
typedef rack::ui::Button rButton;
|
|
||||||
// typedef rack::ui::MenuItem rMenuItem;
|
|
||||||
typedef rack::widget::Widget rWidget;
|
|
||||||
typedef std::list<rWidget*>::iterator rWidgetIterator;
|
|
||||||
|
|
||||||
rWidget* const layout = fContext->scene->menuBar->children.front();
|
|
||||||
|
|
||||||
for (rWidgetIterator it = layout->children.begin(); it != layout->children.end(); ++it)
|
|
||||||
{
|
{
|
||||||
if (rButton* const button = reinterpret_cast<rButton*>(*it))
|
const ScopedContext sc(this);
|
||||||
|
|
||||||
|
fContext->event = new rack::widget::EventState;
|
||||||
|
fContext->scene = new rack::app::Scene;
|
||||||
|
fContext->event->rootWidget = fContext->scene;
|
||||||
|
|
||||||
|
rack::window::WindowInit(fContext->window, this);
|
||||||
|
|
||||||
|
// Hide non-wanted menu entries
|
||||||
|
typedef rack::ui::Button rButton;
|
||||||
|
// typedef rack::ui::MenuItem rMenuItem;
|
||||||
|
typedef rack::widget::Widget rWidget;
|
||||||
|
typedef std::list<rWidget*>::iterator rWidgetIterator;
|
||||||
|
|
||||||
|
rWidget* const layout = fContext->scene->menuBar->children.front();
|
||||||
|
|
||||||
|
for (rWidgetIterator it = layout->children.begin(); it != layout->children.end(); ++it)
|
||||||
{
|
{
|
||||||
/* FIXME this doesnt work
|
if (rButton* const button = reinterpret_cast<rButton*>(*it))
|
||||||
if (button->text == "Engine")
|
|
||||||
{
|
{
|
||||||
for (rWidgetIterator it2 = button->children.begin(); it2 != button->children.end(); ++it2)
|
/* FIXME this doesnt work
|
||||||
|
if (button->text == "Engine")
|
||||||
{
|
{
|
||||||
if (rMenuItem* const item = reinterpret_cast<rMenuItem*>(*it2))
|
for (rWidgetIterator it2 = button->children.begin(); it2 != button->children.end(); ++it2)
|
||||||
{
|
{
|
||||||
if (item->text == "Sample rate")
|
if (rMenuItem* const item = reinterpret_cast<rMenuItem*>(*it2))
|
||||||
{
|
{
|
||||||
button->children.erase(it2);
|
if (item->text == "Sample rate")
|
||||||
delete button;
|
{
|
||||||
break;
|
button->children.erase(it2);
|
||||||
|
delete button;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
*/
|
if (button->text == "Library")
|
||||||
if (button->text == "Library")
|
{
|
||||||
{
|
layout->children.erase(it);
|
||||||
layout->children.erase(it);
|
delete button;
|
||||||
delete button;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to reload current patch for things to show on screen :(
|
||||||
|
// FIXME always save
|
||||||
|
if (! fContext->patch->hasAutosave())
|
||||||
|
fContext->patch->saveAutosave();
|
||||||
|
fContext->patch->loadAutosave();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to reload current patch for things to show on screen :(
|
WindowParametersSetCallback(fContext->window, this);
|
||||||
// FIXME always save
|
|
||||||
if (! fContext->patch->hasAutosave())
|
|
||||||
fContext->patch->saveAutosave();
|
|
||||||
fContext->patch->loadAutosave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~CardinalUI() override
|
~CardinalUI() override
|
||||||
|
|
@ -143,7 +161,6 @@ public:
|
||||||
void onNanoDisplay() override
|
void onNanoDisplay() override
|
||||||
{
|
{
|
||||||
const ScopedContext sc(this);
|
const ScopedContext sc(this);
|
||||||
|
|
||||||
fContext->window->step();
|
fContext->window->step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,6 +169,35 @@ public:
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowParametersChanged(const WindowParameterList param, const float value) override
|
||||||
|
{
|
||||||
|
float mult;
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case kWindowParameterCableOpacity:
|
||||||
|
mult = 100.0f;
|
||||||
|
fWindowParameters.cableOpacity = value;
|
||||||
|
break;
|
||||||
|
case kWindowParameterCableTension:
|
||||||
|
mult = 100.0f;
|
||||||
|
fWindowParameters.cableTension = value;
|
||||||
|
break;
|
||||||
|
case kWindowParameterRackBrightness:
|
||||||
|
mult = 100.0f;
|
||||||
|
fWindowParameters.rackBrightness = value;
|
||||||
|
break;
|
||||||
|
case kWindowParameterHaloBrightness:
|
||||||
|
mult = 100.0f;
|
||||||
|
fWindowParameters.haloBrightness = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setParameterValue((uint)param, value * mult);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* DSP/Plugin Callbacks */
|
* DSP/Plugin Callbacks */
|
||||||
|
|
@ -160,7 +206,30 @@ protected:
|
||||||
A parameter has changed on the plugin side.
|
A parameter has changed on the plugin side.
|
||||||
This is called by the host to inform the UI about parameter changes.
|
This is called by the host to inform the UI about parameter changes.
|
||||||
*/
|
*/
|
||||||
void parameterChanged(uint32_t index, float value) override
|
void parameterChanged(const uint32_t index, const float value) override
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case kWindowParameterCableOpacity:
|
||||||
|
fWindowParameters.cableOpacity = value / 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterCableTension:
|
||||||
|
fWindowParameters.cableTension = value / 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterRackBrightness:
|
||||||
|
fWindowParameters.rackBrightness = value / 100.0f;
|
||||||
|
break;
|
||||||
|
case kWindowParameterHaloBrightness:
|
||||||
|
fWindowParameters.haloBrightness = value / 100.0f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowParametersSetValues(fContext->window, fWindowParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stateChanged(const char* key, const char* value) override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
#define DISTRHO_PLUGIN_HAS_UI 1
|
#define DISTRHO_PLUGIN_HAS_UI 1
|
||||||
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
||||||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
|
||||||
|
#define DISTRHO_PLUGIN_WANT_FULL_STATE 1
|
||||||
|
#define DISTRHO_PLUGIN_WANT_STATE 1
|
||||||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
|
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
|
||||||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1
|
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1
|
||||||
// #define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:AnalyserPlugin"
|
// #define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:AnalyserPlugin"
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "DistrhoPlugin.hpp"
|
#include "DistrhoPlugin.hpp"
|
||||||
|
#include "extra/Mutex.hpp"
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
|
@ -39,6 +40,9 @@ public:
|
||||||
virtual bool canAssignDevice() const noexcept = 0;
|
virtual bool canAssignDevice() const noexcept = 0;
|
||||||
virtual void assignDevice(rack::audio::Device* dev) noexcept = 0;
|
virtual void assignDevice(rack::audio::Device* dev) noexcept = 0;
|
||||||
virtual bool clearDevice(rack::audio::Device* dev) noexcept = 0;
|
virtual bool clearDevice(rack::audio::Device* dev) noexcept = 0;
|
||||||
|
|
||||||
|
// ensure context validity through UI and setState
|
||||||
|
Mutex contextMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -110,7 +114,7 @@ struct CardinalAudioDriver : rack::audio::Driver {
|
||||||
|
|
||||||
std::vector<int> getDeviceIds() override
|
std::vector<int> getDeviceIds() override
|
||||||
{
|
{
|
||||||
return std::vector<int>({ 0 });
|
return std::vector<int>({ 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDeviceName(int) override
|
std::string getDeviceName(int) override
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "DistrhoUI.hpp"
|
#include "DistrhoUI.hpp"
|
||||||
|
#include "WindowParameters.hpp"
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace window {
|
namespace window {
|
||||||
|
|
@ -67,13 +68,19 @@ std::shared_ptr<Image> Image::load(const std::string& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Window::Internal {
|
struct WindowParams {
|
||||||
int mods = 0;
|
float rackBrightness = 1.0f;
|
||||||
DISTRHO_NAMESPACE::UI* ui = nullptr;
|
};
|
||||||
math::Vec size = minWindowSize;
|
|
||||||
|
|
||||||
|
struct Window::Internal {
|
||||||
|
DISTRHO_NAMESPACE::UI* ui = nullptr;
|
||||||
|
DISTRHO_NAMESPACE::WindowParameters params;
|
||||||
|
DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr;
|
||||||
|
|
||||||
|
math::Vec size = minWindowSize;
|
||||||
std::string lastWindowTitle;
|
std::string lastWindowTitle;
|
||||||
|
|
||||||
|
int mods = 0;
|
||||||
int frame = 0;
|
int frame = 0;
|
||||||
int frameSwapInterval = 1;
|
int frameSwapInterval = 1;
|
||||||
double monitorRefreshRate = 60.0; // FIXME
|
double monitorRefreshRate = 60.0; // FIXME
|
||||||
|
|
@ -107,6 +114,9 @@ void WindowInit(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
||||||
window->uiFont = window->loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
|
window->uiFont = window->loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
|
||||||
bndSetFont(window->uiFont->handle);
|
bndSetFont(window->uiFont->handle);
|
||||||
|
|
||||||
|
// Init settings
|
||||||
|
WindowParametersRestore(window);
|
||||||
|
|
||||||
if (APP->scene) {
|
if (APP->scene) {
|
||||||
widget::Widget::ContextCreateEvent e;
|
widget::Widget::ContextCreateEvent e;
|
||||||
APP->scene->onContextCreate(e);
|
APP->scene->onContextCreate(e);
|
||||||
|
|
@ -321,3 +331,59 @@ bool& Window::fbDirtyOnSubpixelChange() {
|
||||||
|
|
||||||
} // namespace window
|
} // namespace window
|
||||||
} // namespace rack
|
} // namespace rack
|
||||||
|
|
||||||
|
|
||||||
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
void WindowParametersSave(rack::window::Window* const window)
|
||||||
|
{
|
||||||
|
if (d_isNotEqual(window->internal->params.cableOpacity, rack::settings::cableOpacity))
|
||||||
|
{
|
||||||
|
window->internal->params.cableOpacity = rack::settings::cableOpacity;
|
||||||
|
if (window->internal->callback != nullptr)
|
||||||
|
window->internal->callback->WindowParametersChanged(kWindowParameterCableOpacity,
|
||||||
|
rack::settings::cableOpacity);
|
||||||
|
}
|
||||||
|
if (d_isNotEqual(window->internal->params.cableTension, rack::settings::cableTension))
|
||||||
|
{
|
||||||
|
window->internal->params.cableTension = rack::settings::cableTension;
|
||||||
|
if (window->internal->callback != nullptr)
|
||||||
|
window->internal->callback->WindowParametersChanged(kWindowParameterCableTension,
|
||||||
|
rack::settings::cableTension);
|
||||||
|
}
|
||||||
|
if (d_isNotEqual(window->internal->params.rackBrightness, rack::settings::rackBrightness))
|
||||||
|
{
|
||||||
|
window->internal->params.rackBrightness = rack::settings::rackBrightness;
|
||||||
|
if (window->internal->callback != nullptr)
|
||||||
|
window->internal->callback->WindowParametersChanged(kWindowParameterRackBrightness,
|
||||||
|
rack::settings::rackBrightness);
|
||||||
|
}
|
||||||
|
if (d_isNotEqual(window->internal->params.haloBrightness, rack::settings::haloBrightness))
|
||||||
|
{
|
||||||
|
window->internal->params.haloBrightness = rack::settings::haloBrightness;
|
||||||
|
if (window->internal->callback != nullptr)
|
||||||
|
window->internal->callback->WindowParametersChanged(kWindowParameterHaloBrightness,
|
||||||
|
rack::settings::haloBrightness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowParametersRestore(rack::window::Window* const window)
|
||||||
|
{
|
||||||
|
rack::settings::cableOpacity = window->internal->params.cableOpacity;
|
||||||
|
rack::settings::cableTension = window->internal->params.cableTension;
|
||||||
|
rack::settings::rackBrightness = window->internal->params.rackBrightness;
|
||||||
|
rack::settings::haloBrightness = window->internal->params.haloBrightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowParametersSetCallback(rack::window::Window* const window, WindowParametersCallback* const callback)
|
||||||
|
{
|
||||||
|
window->internal->callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowParametersSetValues(rack::window::Window* const window, const WindowParameters& params)
|
||||||
|
{
|
||||||
|
window->internal->params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
|
|
||||||
60
src/WindowParameters.hpp
Normal file
60
src/WindowParameters.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* DISTRHO Cardinal Plugin
|
||||||
|
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 3 of
|
||||||
|
* the License, or any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* For a full copy of the GNU General Public License see the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DistrhoUtils.hpp"
|
||||||
|
|
||||||
|
namespace rack {
|
||||||
|
namespace window {
|
||||||
|
struct Window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum WindowParameterList {
|
||||||
|
kWindowParameterCableOpacity,
|
||||||
|
kWindowParameterCableTension,
|
||||||
|
kWindowParameterRackBrightness,
|
||||||
|
kWindowParameterHaloBrightness,
|
||||||
|
kWindowParameterCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowParameters {
|
||||||
|
float cableOpacity = 0.5f;
|
||||||
|
float cableTension = 0.5f;
|
||||||
|
float rackBrightness = 1.0f;
|
||||||
|
float haloBrightness = 0.25f;
|
||||||
|
// KnobMode knobMode = KNOB_MODE_LINEAR;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowParametersCallback {
|
||||||
|
virtual ~WindowParametersCallback() {}
|
||||||
|
virtual void WindowParametersChanged(WindowParameterList param, float value) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void WindowParametersSave(rack::window::Window* window);
|
||||||
|
void WindowParametersRestore(rack::window::Window* window);
|
||||||
|
void WindowParametersSetCallback(rack::window::Window* window, WindowParametersCallback* callback);
|
||||||
|
void WindowParametersSetValues(rack::window::Window* window, const WindowParameters& params);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
END_NAMESPACE_DISTRHO
|
||||||
Loading…
Add table
Add a link
Reference in a new issue