commit 358da5aa4dc1b11c928a92b543f8b2e568be26bc
parent 99781c4541a1bb608044e63725f9efc1fd869feb
Author: falkTX <falktx@falktx.com>
Date: Thu, 27 May 2021 23:01:54 +0100
Start rework of core UI class, special attention to size
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
10 files changed, 350 insertions(+), 390 deletions(-)
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -367,6 +367,10 @@ protected:
A function called when the window is attempted to be closed.
Returning true closes the window, which is the default behaviour.
Override this method and return false to prevent the window from being closed by the user.
+
+ This method is not used for embed windows, and not even made available in DISTRHO_NAMESPACE::UI.
+ For embed windows, closing is handled by the host/parent process and we have no control over it.
+ As such, a close action on embed windows will always succeed and cannot be cancelled.
*/
virtual bool onClose();
diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp
@@ -237,26 +237,46 @@ protected:
* UI Callbacks (optional) */
/**
- uiIdle.
- @TODO Document this.
+ UI idle function, called to give idle time to the plugin UI directly from the host.
+ This is called right after OS event handling and Window idle events (within the same cycle).
+ There are no guarantees in terms of timing.
+ @see addIdleCallback(IdleCallback*, uint).
*/
virtual void uiIdle() {}
-# ifndef DGL_FILE_BROWSER_DISABLED
/**
- File browser selected function.
- @see Window::onFileSelected(const char*)
+ Windows focus function, called when the window gains or loses the keyboard focus.
+ This function is for plugin UIs to be able to override Window::onFocus(bool, CrossingMode).
+
+ The default implementation does nothing.
*/
- virtual void uiFileBrowserSelected(const char* filename);
-# endif
+ virtual void uiFocus(bool focus, CrossingMode mode);
/**
- OpenGL window reshape function, called when parent window is resized.
- You can reimplement this function for a custom OpenGL state.
- @see Window::onReshape(uint,uint)
+ Window reshape function, called when the window is resized.
+ This function is for plugin UIs to be able to override Window::onReshape(uint, uint).
+
+ The plugin UI size will be set right after this function.
+ The default implementation sets up drawing context where necessary.
+
+ You should almost never need to override this function.
+ The most common exception is custom OpenGL setup, but only really needed for custom OpenGL drawing code.
*/
virtual void uiReshape(uint width, uint height);
+# ifndef DGL_FILE_BROWSER_DISABLED
+ /**
+ Window file selected function, called when a path is selected by the user, as triggered by openFileBrowser().
+ This function is for plugin UIs to be able to override Window::onFileSelected(const char*).
+
+ This action happens after the user confirms the action, so the file browser dialog will be closed at this point.
+ The default implementation does nothing.
+
+ If you need to use files as plugin state, please setup and use DISTRHO_PLUGIN_WANT_STATEFILES instead.
+ */
+ virtual void uiFileBrowserSelected(const char* filename);
+# endif
+
/* --------------------------------------------------------------------------------------------------------
* UI Resize Handling, internal */
@@ -265,7 +285,7 @@ protected:
This is overriden here so the host knows when the UI is resized by you.
@see Widget::onResize(const ResizeEvent&)
*/
- void onResize(const ResizeEvent& ev) override;
+// void onResize(const ResizeEvent& ev) override;
#endif
// -------------------------------------------------------------------------------------------------------
@@ -273,8 +293,8 @@ protected:
private:
struct PrivateData;
PrivateData* const uiData;
+ friend class PluginWindow;
friend class UIExporter;
- friend class UIExporterWindow;
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
};
diff --git a/distrho/extra/ScopedPointer.hpp b/distrho/extra/ScopedPointer.hpp
@@ -146,6 +146,9 @@ public:
ObjectType* get() const noexcept { return object; }
/** Returns the object that this ScopedPointer refers to. */
+ ObjectType& getObject() const noexcept { return *object; }
+
+ /** Returns the object that this ScopedPointer refers to. */
ObjectType& operator*() const noexcept { return *object; }
/** Lets you access methods and properties of the object that this ScopedPointer refers to. */
diff --git a/distrho/src/DistrhoPluginJack.cpp b/distrho/src/DistrhoPluginJack.cpp
@@ -17,7 +17,6 @@
#include "DistrhoPluginInternal.hpp"
#if DISTRHO_PLUGIN_HAS_UI
-# define DISTRHO_UI_IS_STANDALONE true
# include "DistrhoUIInternal.hpp"
# include "../extra/RingBuffer.hpp"
#else
@@ -110,7 +109,9 @@ public:
PluginJack(jack_client_t* const client)
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback),
#if DISTRHO_PLUGIN_HAS_UI
- fUI(this, 0,
+ fUI(this,
+ 0, // winId
+ d_lastSampleRate,
nullptr, // edit param
setParameterValueCallback,
setStateCallback,
@@ -301,7 +302,7 @@ protected:
}
}
- fUI.exec_idle();
+ fUI.idle();
}
#endif
@@ -797,9 +798,6 @@ int main()
d_lastBufferSize = jack_get_buffer_size(client);
d_lastSampleRate = jack_get_sample_rate(client);
-#if DISTRHO_PLUGIN_HAS_UI
- d_lastUiSampleRate = d_lastSampleRate;
-#endif
const PluginJack p(client);
diff --git a/distrho/src/DistrhoPluginVST.cpp b/distrho/src/DistrhoPluginVST.cpp
@@ -25,7 +25,6 @@
#if DISTRHO_PLUGIN_HAS_UI
# undef DISTRHO_UI_USER_RESIZABLE
# define DISTRHO_UI_USER_RESIZABLE 0
-# define DISTRHO_UI_IS_STANDALONE false
# include "DistrhoUIInternal.hpp"
# include "../extra/RingBuffer.hpp"
#endif
@@ -178,7 +177,7 @@ public:
fEffect(effect),
fUiHelper(uiHelper),
fPlugin(plugin),
- fUI(this, winId,
+ fUI(this, winId, plugin->getSampleRate(),
editParameterCallback,
setParameterCallback,
setStateCallback,
@@ -671,9 +670,7 @@ public:
}
else
{
- d_lastUiSampleRate = fPlugin.getSampleRate();
-
- UIExporter tmpUI(nullptr, 0,
+ UIExporter tmpUI(nullptr, 0,fPlugin.getSampleRate(),
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
fPlugin.getInstancePointer(), fLastScaleFactor);
fVstRect.right = tmpUI.getWidth();
@@ -694,8 +691,6 @@ public:
return 0;
}
# endif
- d_lastUiSampleRate = fPlugin.getSampleRate();
-
fVstUI = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr, fLastScaleFactor);
# if DISTRHO_PLUGIN_WANT_FULL_STATE
diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp
@@ -20,71 +20,38 @@
# include "src/TopLevelWidgetPrivateData.hpp"
#endif
-#include "NanoVG.hpp"
-
START_NAMESPACE_DISTRHO
/* ------------------------------------------------------------------------------------------------------------
- * Static data, see DistrhoUIInternal.hpp and DistrhoUIPrivateData.hpp */
+ * Static data, see DistrhoUIInternal.hpp */
-double d_lastUiSampleRate = 0.0;
-void* d_lastUiDspPtr = nullptr;
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-const char* g_nextBundlePath = nullptr;
-double g_nextScaleFactor = 1.0;
-uintptr_t g_nextWindowId = 0;
-#else
-Window* d_lastUiWindow = nullptr;
+uintptr_t g_nextWindowId = 0;
+double g_nextScaleFactor = 1.0;
+const char* g_nextBundlePath = nullptr;
#endif
-// -----------------------------------------------------------------------------------------------------------
+/* ------------------------------------------------------------------------------------------------------------
+ * UI::PrivateData special handling */
-#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath)
-{
- d_lastUiDspPtr = dspPtr;
- g_nextWindowId = winId;
- g_nextScaleFactor = scaleFactor;
- g_nextBundlePath = bundlePath;
- UI* const ret = createUI();
- d_lastUiDspPtr = nullptr;
- g_nextWindowId = 0;
- g_nextScaleFactor = 1.0;
- g_nextBundlePath = nullptr;
- return ret;
-}
-#else
-UI* createUiWrapper(void* const dspPtr, Window* const window)
-{
- d_lastUiDspPtr = dspPtr;
- d_lastUiWindow = window;
- UI* const ret = createUI();
- d_lastUiDspPtr = nullptr;
- d_lastUiWindow = nullptr;
- return ret;
-}
-#endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+UI::PrivateData* UI::PrivateData::s_nextPrivateData = nullptr;
+
+PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint height)
+{
+ UI::PrivateData* const pData = s_nextPrivateData;
+ pData->window = new PluginWindow(ui, pData, width, height);
+ return pData->window.getObject();
+}
/* ------------------------------------------------------------------------------------------------------------
* UI */
-#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-UI::UI(uint width, uint height)
- : UIWidget(width, height),
- uiData(new PrivateData()) {}
-#else
-UI::UI(uint width, uint height)
- : UIWidget(*d_lastUiWindow),
- uiData(new PrivateData())
-{
- if (width > 0 && height > 0)
- setSize(width, height);
-}
-#endif
+UI::UI(const uint width, const uint height)
+ : UIWidget(UI::PrivateData::createNextWindow(this, width, height)),
+ uiData(UI::PrivateData::s_nextPrivateData) {}
UI::~UI()
{
- delete uiData;
}
/* ------------------------------------------------------------------------------------------------------------
@@ -166,22 +133,22 @@ uintptr_t UI::getNextWindowId() noexcept
return g_nextWindowId;
}
# endif
-#endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+#endif
/* ------------------------------------------------------------------------------------------------------------
* DSP/Plugin Callbacks (optional) */
-void UI::sampleRateChanged(double) {}
+void UI::sampleRateChanged(double)
+{
+}
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
/* ------------------------------------------------------------------------------------------------------------
* UI Callbacks (optional) */
-# ifndef DGL_FILE_BROWSER_DISABLED
-void UI::uiFileBrowserSelected(const char*)
+void UI::uiFocus(bool, CrossingMode)
{
}
-# endif
void UI::uiReshape(uint, uint)
{
@@ -189,33 +156,32 @@ void UI::uiReshape(uint, uint)
pData->fallbackOnResize();
}
-/* ------------------------------------------------------------------------------------------------------------
- * UI Resize Handling, internal */
-
-void UI::onResize(const ResizeEvent& ev)
+# ifndef DGL_FILE_BROWSER_DISABLED
+void UI::uiFileBrowserSelected(const char*)
{
- if (uiData->resizeInProgress)
- return;
-
- UIWidget::onResize(ev);
+}
+# endif
- const uint width = ev.size.getWidth();
- const uint height = ev.size.getHeight();
+/* ------------------------------------------------------------------------------------------------------------
+ * UI Resize Handling, internal */
- /*
- pData->window.setSize(width, height);
- */
- uiData->setSizeCallback(width, height);
-}
+// void UI::onResize(const ResizeEvent& ev)
+// {
+// if (uiData->resizeInProgress)
+// return;
+//
+// UIWidget::onResize(ev);
+//
+// const uint width = ev.size.getWidth();
+// const uint height = ev.size.getHeight();
+//
+// /*
+// pData->window.setSize(width, height);
+// */
+// uiData->setSizeCallback(width, height);
+// }
#endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
// -----------------------------------------------------------------------------------------------------------
END_NAMESPACE_DISTRHO
-
-// -----------------------------------------------------------------------
-// Possible template data types
-
-// template class NanoBaseWidget<SubWidget>;
-// template class NanoBaseWidget<TopLevelWidget>;
-// template class NanoBaseWidget<StandaloneWindow>;
diff --git a/distrho/src/DistrhoUIDSSI.cpp b/distrho/src/DistrhoUIDSSI.cpp
@@ -14,7 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define DISTRHO_UI_IS_STANDALONE true
#include "DistrhoUIInternal.hpp"
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
@@ -97,8 +96,9 @@ struct OscData {
class UIDssi
{
public:
- UIDssi(const OscData& oscData, const char* const uiTitle)
- : fUI(this, 0, nullptr, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, nullptr),
+ UIDssi(const OscData& oscData, const char* const uiTitle, const double sampleRate)
+ : fUI(this, 0, sampleRate, nullptr,
+ setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, nullptr),
fHostClosed(false),
fOscData(oscData)
{
@@ -252,16 +252,17 @@ private:
static OscData gOscData;
static const char* gUiTitle = nullptr;
static UIDssi* globalUI = nullptr;
+static double sampleRate = 0.0;
static void initUiIfNeeded()
{
if (globalUI != nullptr)
return;
- if (d_lastUiSampleRate == 0.0)
- d_lastUiSampleRate = 44100.0;
+ if (sampleRate == 0.0)
+ sampleRate = 44100.0;
- globalUI = new UIDssi(gOscData, gUiTitle);
+ globalUI = new UIDssi(gOscData, gUiTitle, sampleRate);
}
// -----------------------------------------------------------------------
@@ -337,10 +338,8 @@ int osc_program_handler(const char*, const char*, lo_arg** argv, int, lo_message
int osc_sample_rate_handler(const char*, const char*, lo_arg** argv, int, lo_message, void*)
{
- const int32_t sampleRate = argv[0]->i;
- d_debug("osc_sample_rate_handler(%i)", sampleRate);
-
- d_lastUiSampleRate = sampleRate;
+ sampleRate = argv[0]->i;
+ d_debug("osc_sample_rate_handler(%f)", sampleRate);
if (globalUI != nullptr)
globalUI->dssiui_samplerate(sampleRate);
@@ -481,7 +480,7 @@ int main(int argc, char* argv[])
{
lo_server_recv(oscServer);
- if (d_lastUiSampleRate != 0.0 || globalUI != nullptr)
+ if (sampleRate != 0.0 || globalUI != nullptr)
break;
d_msleep(50);
@@ -489,7 +488,7 @@ int main(int argc, char* argv[])
int ret = 1;
- if (d_lastUiSampleRate != 0.0 || globalUI != nullptr)
+ if (sampleRate != 0.0 || globalUI != nullptr)
{
initUiIfNeeded();
diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp
@@ -21,13 +21,6 @@
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
# include "../extra/Sleep.hpp"
-using DGL_NAMESPACE::IdleCallback;
-#else
-# include "../../dgl/Application.hpp"
-# include "../../dgl/Window.hpp"
-using DGL_NAMESPACE::Application;
-using DGL_NAMESPACE::IdleCallback;
-using DGL_NAMESPACE::Window;
#endif
START_NAMESPACE_DISTRHO
@@ -35,121 +28,32 @@ START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------
// Static data, see DistrhoUI.cpp
-extern double d_lastUiSampleRate;
-extern void* d_lastUiDspPtr;
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-extern const char* g_nextBundlePath;
-extern double g_nextScaleFactor;
extern uintptr_t g_nextWindowId;
-#else
-extern Window* d_lastUiWindow;
-#endif
-
-// -----------------------------------------------------------------------
-
-#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath);
-#else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-UI* createUiWrapper(void* const dspPtr, Window* const window);
-#endif
-
-#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-// -----------------------------------------------------------------------
-// Plugin Application, will set class name based on plugin details
-
-class PluginApplication : public Application
-{
-public:
- PluginApplication()
- : Application(DISTRHO_UI_IS_STANDALONE)
- {
- const char* const className = (
-#ifdef DISTRHO_PLUGIN_BRAND
- DISTRHO_PLUGIN_BRAND
-#else
- DISTRHO_MACRO_AS_STRING(DISTRHO_NAMESPACE)
+extern double g_nextScaleFactor;
+extern const char* g_nextBundlePath;
#endif
- "-" DISTRHO_PLUGIN_NAME
- );
- setClassName(className);
- }
-};
// -----------------------------------------------------------------------
-// Plugin Window, needed to take care of resize properly
+// UI exporter class
-class UIExporterWindow : public Window
+class UIExporter
{
-public:
- UIExporterWindow(PluginApplication& app, const intptr_t winId, const double scaleFactor, void* const dspPtr)
- : Window(app, winId, scaleFactor, DISTRHO_UI_USER_RESIZABLE),
- fUI(createUiWrapper(dspPtr, this)),
- fIsReady(false)
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(fUI->uiData != nullptr,);
-
- setSize(fUI->getWidth(), fUI->getHeight());
- }
-
- ~UIExporterWindow()
- {
- delete fUI;
- }
-
- UI* getUI() const noexcept
- {
- return fUI;
- }
-
- bool isReady() const noexcept
- {
- return fIsReady;
- }
-
-protected:
- // custom window reshape
- void onReshape(uint width, uint height) override
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
-
- UI::PrivateData* const uiData = fUI->uiData;
- DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,);
-
- /*
- uiData->resizeInProgress = true;
- fUI->setSize(width, height);
- uiData->resizeInProgress = false;
- */
-
- fUI->uiReshape(width, height);
- fIsReady = true;
- }
+ // -------------------------------------------------------------------
+ // UI Widget and its private data
-# ifndef DGL_FILE_BROWSER_DISABLED
- // custom file-browser selected
- void onFileSelected(const char* const filename) override
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ UI* ui;
+ UI::PrivateData* uiData;
- fUI->uiFileBrowserSelected(filename);
- }
-# endif
+ // prevent resize recursion
+ bool changingSizeRecursionCheck;
-private:
- UI* const fUI;
- bool fIsReady;
-};
-#endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI
-
-// -----------------------------------------------------------------------
-// UI exporter class
+ // -------------------------------------------------------------------
-class UIExporter
-{
public:
UIExporter(void* const callbacksPtr,
- const intptr_t winId,
+ const uintptr_t winId,
+ const double sampleRate,
const editParamFunc editParamCall,
const setParamFunc setParamCall,
const setStateFunc setStateCall,
@@ -161,139 +65,130 @@ public:
const double scaleFactor = 1.0,
const uint32_t bgColor = 0,
const uint32_t fgColor = 0xffffffff)
-#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- : fUI(createUiWrapper(dspPtr, winId, scaleFactor, bundlePath)),
-#else
- : glApp(),
- glWindow(glApp, winId, scaleFactor, dspPtr),
- fChangingSize(false),
- fUI(glWindow.getUI()),
-#endif
- fData((fUI != nullptr) ? fUI->uiData : nullptr)
+ : ui(nullptr),
+ uiData(new UI::PrivateData()),
+ changingSizeRecursionCheck(false)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
-
- fData->bgColor = bgColor;
- fData->fgColor = fgColor;
-
- fData->callbacksPtr = callbacksPtr;
- fData->editParamCallbackFunc = editParamCall;
- fData->setParamCallbackFunc = setParamCall;
- fData->setStateCallbackFunc = setStateCall;
- fData->sendNoteCallbackFunc = sendNoteCall;
- fData->setSizeCallbackFunc = setSizeCall;
- fData->fileRequestCallbackFunc = fileRequestCall;
+ uiData->sampleRate = sampleRate;
+ uiData->dspPtr = dspPtr;
+ uiData->bgColor = bgColor;
+ uiData->fgColor = fgColor;
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- // unused
- return; (void)bundlePath;
+ uiData->scaleFactor = scaleFactor;
+ uiData->winId = winId;
#endif
- }
+
+ uiData->callbacksPtr = callbacksPtr;
+ uiData->editParamCallbackFunc = editParamCall;
+ uiData->setParamCallbackFunc = setParamCall;
+ uiData->setStateCallbackFunc = setStateCall;
+ uiData->sendNoteCallbackFunc = sendNoteCall;
+ uiData->setSizeCallbackFunc = setSizeCall;
+ uiData->fileRequestCallbackFunc = fileRequestCall;
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- ~UIExporter()
- {
- delete fUI;
- }
+ g_nextWindowId = winId;
+ g_nextScaleFactor = scaleFactor;
+ g_nextBundlePath = bundlePath;
#endif
+ UI::PrivateData::s_nextPrivateData = uiData;
- // -------------------------------------------------------------------
+ UI* const uiPtr = createUI();
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- uint getWidth() const noexcept
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1);
- return fUI->getWidth();
- }
+ g_nextWindowId = 0;
+ g_nextScaleFactor = 0.0;
+ g_nextBundlePath = nullptr;
+#endif
+ UI::PrivateData::s_nextPrivateData = nullptr;
- uint getHeight() const noexcept
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1);
- return fUI->getHeight();
- }
+ DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,);
+ ui = uiPtr;
- bool isVisible() const noexcept
- {
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false);
- return fUI->isRunning();
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+ // unused
+ (void)bundlePath;
+#endif
}
- uintptr_t getNativeWindowHandle() const noexcept
+ ~UIExporter()
{
- return 0;
+ delete ui;
+ delete uiData;
}
-#else
+
+ // -------------------------------------------------------------------
+
uint getWidth() const noexcept
{
- return glWindow.getWidth();
+ return uiData->window->getWidth();
}
uint getHeight() const noexcept
{
- return glWindow.getHeight();
+ return uiData->window->getHeight();
}
bool isVisible() const noexcept
{
- return glWindow.isVisible();
+ return uiData->window->isVisible();
}
uintptr_t getNativeWindowHandle() const noexcept
{
- return glWindow.getNativeWindowHandle();
+ return uiData->window->getNativeWindowHandle();
}
-#endif
uint getBackgroundColor() const noexcept
{
- DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
+ DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
- return fData->bgColor;
+ return uiData->bgColor;
}
uint getForegroundColor() const noexcept
{
- DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0xffffffff);
+ DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0xffffffff);
- return fData->fgColor;
+ return uiData->fgColor;
}
// -------------------------------------------------------------------
uint32_t getParameterOffset() const noexcept
{
- DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
+ DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
- return fData->parameterOffset;
+ return uiData->parameterOffset;
}
// -------------------------------------------------------------------
void parameterChanged(const uint32_t index, const float value)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->parameterChanged(index, value);
+ ui->parameterChanged(index, value);
}
#if DISTRHO_PLUGIN_WANT_PROGRAMS
void programLoaded(const uint32_t index)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->programLoaded(index);
+ ui->programLoaded(index);
}
#endif
#if DISTRHO_PLUGIN_WANT_STATE
void stateChanged(const char* const key, const char* const value)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);
- fUI->stateChanged(key, value);
+ ui->stateChanged(key, value);
}
#endif
@@ -303,12 +198,12 @@ public:
void exec(IdleCallback* const cb)
{
DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->setVisible(true);
+ ui->setVisible(true);
cb->idleCallback();
- while (fUI->isRunning())
+ while (ui->isRunning())
{
d_msleep(10);
cb->idleCallback();
@@ -330,49 +225,38 @@ public:
void quit()
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->setVisible(false);
- fUI->terminateAndWaitForProcess();
+ ui->setVisible(false);
+ ui->terminateAndWaitForProcess();
}
#else
void exec(IdleCallback* const cb)
{
DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
- glWindow.setVisible(true);
- glApp.addIdleCallback(cb);
- glApp.exec();
- }
-
- void exec_idle()
- {
- if (glWindow.isReady())
- fUI->uiIdle();
+ uiData->window->show();
+ uiData->app.addIdleCallback(cb);
+ uiData->app.exec();
}
void focus()
{
- glWindow.focus();
+ uiData->window->focus();
}
bool idle()
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false);
- glApp.idle();
-
- if (glWindow.isReady())
- fUI->uiIdle();
-
- return ! glApp.isQuiting();
+ ui->uiIdle();
+ return ! uiData->app.isQuiting();
}
void quit()
{
- glWindow.close();
- glApp.quit();
+ uiData->window->close();
+ uiData->app.quit();
}
#endif
@@ -381,52 +265,46 @@ public:
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
void setWindowTitle(const char* const uiTitle)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->setTitle(uiTitle);
+ ui->setTitle(uiTitle);
}
- void setWindowSize(const uint width, const uint height, const bool = false)
+ void setWindowSize(const uint width, const uint height)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->setSize(width, height);
+ ui->setSize(width, height);
}
void setWindowTransientWinId(const uintptr_t winId)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
- fUI->setTransientWinId(winId);
+ ui->setTransientWinId(winId);
}
bool setWindowVisible(const bool yesNo)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false);
- fUI->setVisible(yesNo);
+ ui->setVisible(yesNo);
- return fUI->isRunning();
+ return ui->isRunning();
}
#else
void setWindowTitle(const char* const uiTitle)
{
- glWindow.setTitle(uiTitle);
+// glWindow.setTitle(uiTitle);
}
- void setWindowSize(const uint width, const uint height, const bool updateUI = false)
+ void setWindowSize(const uint width, const uint height)
{
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(! fChangingSize,);
-
- fChangingSize = true;
+ DISTRHO_SAFE_ASSERT_RETURN(! changingSizeRecursionCheck,);
- if (updateUI)
- fUI->setSize(width, height);
-
- glWindow.setSize(width, height);
-
- fChangingSize = false;
+ changingSizeRecursionCheck = true;
+// glWindow.setSize(width, height);
+ changingSizeRecursionCheck = false;
}
void setWindowTransientWinId(const uintptr_t /*winId*/)
@@ -438,9 +316,10 @@ public:
bool setWindowVisible(const bool yesNo)
{
- glWindow.setVisible(yesNo);
+// glWindow.setVisible(yesNo);
- return ! glApp.isQuiting();
+// return ! glApp.isQuiting();
+ return true;
}
bool handlePluginKeyboard(const bool /*press*/, const uint /*key*/, const uint16_t /*mods*/)
@@ -464,37 +343,19 @@ public:
void setSampleRate(const double sampleRate, const bool doCallback = false)
{
- DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
- DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,);
DISTRHO_SAFE_ASSERT(sampleRate > 0.0);
- if (d_isEqual(fData->sampleRate, sampleRate))
+ if (d_isEqual(uiData->sampleRate, sampleRate))
return;
- fData->sampleRate = sampleRate;
+ uiData->sampleRate = sampleRate;
if (doCallback)
- fUI->sampleRateChanged(sampleRate);
+ ui->sampleRateChanged(sampleRate);
}
-private:
-#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- // -------------------------------------------------------------------
- // DGL Application and Window for this widget
-
- PluginApplication glApp;
- UIExporterWindow glWindow;
-
- // prevent recursion
- bool fChangingSize;
-#endif
-
- // -------------------------------------------------------------------
- // Widget and DistrhoUI data
-
- UI* const fUI;
- UI::PrivateData* const fData;
-
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter)
};
diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp
@@ -14,7 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define DISTRHO_UI_IS_STANDALONE false
#include "DistrhoUIInternal.hpp"
#include "../extra/String.hpp"
@@ -73,10 +72,11 @@ public:
const LV2UI_Write_Function writeFunc,
LV2UI_Widget* const widget,
void* const dspPtr,
+ const float sampleRate,
const float scaleFactor,
const uint32_t bgColor,
const uint32_t fgColor)
- : fUI(this, winId,
+ : fUI(this, winId, sampleRate,
editParameterCallback,
setParameterCallback,
setStateCallback,
@@ -208,7 +208,8 @@ public:
int lv2ui_resize(uint width, uint height)
{
- fUI.setWindowSize(width, height, true);
+ // FIXME
+ // fUI.setWindowSize(width, height, true);
return 0;
}
@@ -526,6 +527,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*,
#endif
const intptr_t winId = (intptr_t)parentId;
+ float sampleRate = 0.0f;
float scaleFactor = 1.0f;
uint32_t bgColor = 0;
uint32_t fgColor = 0xffffffff;
@@ -544,7 +546,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*,
/**/ if (options[i].key == uridSampleRate)
{
if (options[i].type == uridAtomFloat)
- d_lastUiSampleRate = *(const float*)options[i].value;
+ sampleRate = *(const float*)options[i].value;
else
d_stderr("Host provides UI sample-rate but has wrong value type");
}
@@ -572,15 +574,15 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*,
}
}
- if (d_lastUiSampleRate < 1.0)
+ if (sampleRate < 1.0)
{
d_stdout("WARNING: this host does not send sample-rate information for LV2 UIs, using 44100 as fallback (this could be wrong)");
- d_lastUiSampleRate = 44100.0;
+ sampleRate = 44100.0;
}
return new UiLv2(bundlePath, winId, options, uridMap, features,
controller, writeFunction, widget, instance,
- scaleFactor, bgColor, fgColor);
+ sampleRate, scaleFactor, bgColor, fgColor);
}
#define uiPtr ((UiLv2*)ui)
diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com>
+ * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -18,14 +18,22 @@
#define DISTRHO_UI_PRIVATE_DATA_HPP_INCLUDED
#include "../DistrhoUI.hpp"
+#include "../../dgl/Application.hpp"
-START_NAMESPACE_DISTRHO
+#ifndef DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+# include "../../dgl/Window.hpp"
+#endif
-// -----------------------------------------------------------------------
-// Static data, see DistrhoUI.cpp
+#if defined(DISTRHO_PLUGIN_TARGET_JACK) || defined(DISTRHO_PLUGIN_TARGET_DSSI)
+# define DISTRHO_UI_IS_STANDALONE true
+#else
+# define DISTRHO_UI_IS_STANDALONE false
+#endif
-extern double d_lastUiSampleRate;
-extern void* d_lastUiDspPtr;
+START_NAMESPACE_DISTRHO
+
+using DGL_NAMESPACE::Application;
+using DGL_NAMESPACE::Window;
// -----------------------------------------------------------------------
// UI callbacks
@@ -38,23 +46,50 @@ typedef void (*setSizeFunc) (void* ptr, uint width, uint height);
typedef bool (*fileRequestFunc) (void* ptr, const char* key);
// -----------------------------------------------------------------------
+// Plugin Application, will set class name based on plugin details
+
+class PluginApplication : public Application
+{
+public:
+ explicit PluginApplication()
+ : Application(DISTRHO_UI_IS_STANDALONE)
+ {
+ const char* const className = (
+#ifdef DISTRHO_PLUGIN_BRAND
+ DISTRHO_PLUGIN_BRAND
+#else
+ DISTRHO_MACRO_AS_STRING(DISTRHO_NAMESPACE)
+#endif
+ "-" DISTRHO_PLUGIN_NAME
+ );
+ setClassName(className);
+ }
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginApplication)
+};
+
+class PluginWindow;
+
+// -----------------------------------------------------------------------
// UI private data
struct UI::PrivateData {
+ // DGL
+ PluginApplication app;
+ ScopedPointer<PluginWindow> window;
+
// DSP
double sampleRate;
uint32_t parameterOffset;
-#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
void* dspPtr;
-#endif
// UI
- bool automaticallyScale;
- bool resizeInProgress;
- uint minWidth;
- uint minHeight;
uint bgColor;
uint fgColor;
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+ double scaleFactor;
+ uintptr_t winId;
+#endif
// Callbacks
void* callbacksPtr;
@@ -66,17 +101,19 @@ struct UI::PrivateData {
fileRequestFunc fileRequestCallbackFunc;
PrivateData() noexcept
- : sampleRate(d_lastUiSampleRate),
- parameterOffset(0),
-#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
- dspPtr(d_lastUiDspPtr),
+ : app(),
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+ window(nullptr),
#endif
- automaticallyScale(false),
- resizeInProgress(false),
- minWidth(0),
- minHeight(0),
+ sampleRate(0),
+ parameterOffset(0),
+ dspPtr(nullptr),
bgColor(0),
- fgColor(0),
+ fgColor(0xffffffff),
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+ scaleFactor(1.0),
+ winId(0),
+#endif
callbacksPtr(nullptr),
editParamCallbackFunc(nullptr),
setParamCallbackFunc(nullptr),
@@ -85,8 +122,6 @@ struct UI::PrivateData {
setSizeCallbackFunc(nullptr),
fileRequestCallbackFunc(nullptr)
{
- DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate));
-
#if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)
parameterOffset += DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS;
# if DISTRHO_PLUGIN_WANT_LATENCY
@@ -143,7 +178,84 @@ struct UI::PrivateData {
return false;
}
+
+ static UI::PrivateData* s_nextPrivateData;
+ static PluginWindow& createNextWindow(UI* ui, uint width, uint height);
+};
+
+// -----------------------------------------------------------------------
+// Plugin Window, will pass some Window events to UI
+
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+// TODO external ui stuff
+class PluginWindow
+{
+ UI* const ui;
+
+public:
+ explicit PluginWindow(UI* const uiPtr, UI::PrivateData* const pData, const uint width, const uint height)
+ : Window(pData->app, pData->winId, pData->scaleFactor, width, height, DISTRHO_UI_USER_RESIZABLE),
+ ui(uiPtr) {}
+
+ uint getWidth() const noexcept
+ {
+ return ui->getWidth();
+ }
+
+ uint getHeight() const noexcept
+ {
+ return ui->getHeight();
+ }
+
+ bool isVisible() const noexcept
+ {
+ return ui->isRunning();
+ }
+
+ uintptr_t getNativeWindowHandle() const noexcept
+ {
+ return 0;
+ }
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow)
+};
+#else
+class PluginWindow : public Window
+{
+ UI* const ui;
+
+public:
+ explicit PluginWindow(UI* const uiPtr, UI::PrivateData* const pData, const uint width, const uint height)
+ : Window(pData->app, pData->winId, width, height, pData->scaleFactor, DISTRHO_UI_USER_RESIZABLE),
+ ui(uiPtr) {}
+
+protected:
+ void onFocus(const bool focus, const CrossingMode mode) override
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+ ui->uiFocus(focus, mode);
+ }
+
+ void onReshape(const uint width, const uint height) override
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+ ui->uiReshape(width, height);
+ }
+
+# ifndef DGL_FILE_BROWSER_DISABLED
+ void onFileSelected(const char* const filename) override
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+ ui->uiFileBrowserSelected(filename);
+ }
+# endif
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow)
};
+#endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
// -----------------------------------------------------------------------