diff DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoUIInternal.hpp @ 3:84e66ea83026

DPF-Prymula-audioplugins-0.231015-2
author prymula <prymula76@outlook.com>
date Mon, 16 Oct 2023 21:53:34 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoUIInternal.hpp	Mon Oct 16 21:53:34 2023 +0200
@@ -0,0 +1,414 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2022 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
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef DISTRHO_UI_INTERNAL_HPP_INCLUDED
+#define DISTRHO_UI_INTERNAL_HPP_INCLUDED
+
+#include "DistrhoUIPrivateData.hpp"
+
+START_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------
+// Static data, see DistrhoUI.cpp
+
+extern const char* g_nextBundlePath;
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+extern uintptr_t   g_nextWindowId;
+extern double      g_nextScaleFactor;
+#endif
+
+// -----------------------------------------------------------------------
+// UI exporter class
+
+class UIExporter
+{
+    // -------------------------------------------------------------------
+    // UI Widget and its private data
+
+    UI* ui;
+    UI::PrivateData* uiData;
+
+    // -------------------------------------------------------------------
+
+public:
+    UIExporter(void* const callbacksPtr,
+               const uintptr_t winId,
+               const double sampleRate,
+               const editParamFunc editParamCall,
+               const setParamFunc setParamCall,
+               const setStateFunc setStateCall,
+               const sendNoteFunc sendNoteCall,
+               const setSizeFunc setSizeCall,
+               const fileRequestFunc fileRequestCall,
+               const char* const bundlePath = nullptr,
+               void* const dspPtr = nullptr,
+               const double scaleFactor = 0.0,
+               const uint32_t bgColor = 0,
+               const uint32_t fgColor = 0xffffffff,
+               const char* const appClassName = nullptr)
+        : ui(nullptr),
+          uiData(new UI::PrivateData(appClassName))
+    {
+        uiData->sampleRate = sampleRate;
+        uiData->bundlePath = bundlePath != nullptr ? strdup(bundlePath) : nullptr;
+        uiData->dspPtr = dspPtr;
+
+        uiData->bgColor = bgColor;
+        uiData->fgColor = fgColor;
+        uiData->scaleFactor = scaleFactor;
+        uiData->winId = winId;
+
+        uiData->callbacksPtr            = callbacksPtr;
+        uiData->editParamCallbackFunc   = editParamCall;
+        uiData->setParamCallbackFunc    = setParamCall;
+        uiData->setStateCallbackFunc    = setStateCall;
+        uiData->sendNoteCallbackFunc    = sendNoteCall;
+        uiData->setSizeCallbackFunc     = setSizeCall;
+        uiData->fileRequestCallbackFunc = fileRequestCall;
+
+        g_nextBundlePath  = bundlePath;
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        g_nextWindowId    = winId;
+        g_nextScaleFactor = scaleFactor;
+#endif
+        UI::PrivateData::s_nextPrivateData = uiData;
+
+        UI* const uiPtr = createUI();
+
+        g_nextBundlePath  = nullptr;
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        g_nextWindowId    = 0;
+        g_nextScaleFactor = 0.0;
+#else
+        // enter context called in the PluginWindow constructor, see DistrhoUIPrivateData.hpp
+        uiData->window->leaveContext();
+#endif
+        UI::PrivateData::s_nextPrivateData = nullptr;
+
+        DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,);
+        ui = uiPtr;
+        uiData->initializing = false;
+
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        // unused
+        (void)bundlePath;
+#endif
+    }
+
+    ~UIExporter()
+    {
+        quit();
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        uiData->window->enterContextForDeletion();
+#endif
+        delete ui;
+        delete uiData;
+    }
+
+    // -------------------------------------------------------------------
+
+    uint getWidth() const noexcept
+    {
+        return uiData->window->getWidth();
+    }
+
+    uint getHeight() const noexcept
+    {
+        return uiData->window->getHeight();
+    }
+
+    double getScaleFactor() const noexcept
+    {
+        return uiData->window->getScaleFactor();
+    }
+
+    bool getGeometryConstraints(uint& minimumWidth, uint& minimumHeight, bool& keepAspectRatio) const noexcept
+    {
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        uiData->window->getGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio);
+#else
+        const DGL_NAMESPACE::Size<uint> size(uiData->window->getGeometryConstraints(keepAspectRatio));
+        minimumWidth = size.getWidth();
+        minimumHeight = size.getHeight();
+#endif
+        return true;
+    }
+
+    bool isResizable() const noexcept
+    {
+        return uiData->window->isResizable();
+    }
+
+    bool isVisible() const noexcept
+    {
+        return uiData->window->isVisible();
+    }
+
+    uintptr_t getNativeWindowHandle() const noexcept
+    {
+        return uiData->window->getNativeWindowHandle();
+    }
+
+    uint getBackgroundColor() const noexcept
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
+
+        return uiData->bgColor;
+    }
+
+    uint getForegroundColor() const noexcept
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0xffffffff);
+
+        return uiData->fgColor;
+    }
+
+    // -------------------------------------------------------------------
+
+    uint32_t getParameterOffset() const noexcept
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
+
+        return uiData->parameterOffset;
+    }
+
+    // -------------------------------------------------------------------
+
+    void parameterChanged(const uint32_t index, const float value)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+        ui->parameterChanged(index, value);
+    }
+
+   #if DISTRHO_PLUGIN_WANT_PROGRAMS
+    void programLoaded(const uint32_t index)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+        ui->programLoaded(index);
+    }
+   #endif
+
+   #if DISTRHO_PLUGIN_WANT_STATE
+    void stateChanged(const char* const key, const char* const value)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+        DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
+        DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);
+
+        ui->stateChanged(key, value);
+    }
+   #endif
+
+    // -------------------------------------------------------------------
+
+   #if DISTRHO_UI_IS_STANDALONE
+    void exec(DGL_NAMESPACE::IdleCallback* const cb)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,);
+
+        uiData->window->show();
+        uiData->window->focus();
+        uiData->app.addIdleCallback(cb);
+        uiData->app.exec();
+    }
+
+    void exec_idle()
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, );
+
+        ui->uiIdle();
+    }
+
+    void showAndFocus()
+    {
+        uiData->window->show();
+        uiData->window->focus();
+    }
+   #endif
+
+    bool plugin_idle()
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false);
+
+        uiData->app.idle();
+        ui->uiIdle();
+        return ! uiData->app.isQuitting();
+    }
+
+    void focus()
+    {
+        uiData->window->focus();
+    }
+
+    void quit()
+    {
+        uiData->window->close();
+        uiData->app.quit();
+    }
+
+   #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+    void repaint()
+    {
+        uiData->window->repaint();
+    }
+   #endif
+
+    // -------------------------------------------------------------------
+
+  #if defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS)
+    void idleFromNativeIdle()
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+        uiData->app.triggerIdleCallbacks();
+        ui->uiIdle();
+    }
+
+   #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+    void addIdleCallbackForNativeIdle(IdleCallback* const cb, const uint timerFrequencyInMs)
+    {
+        uiData->window->addIdleCallback(cb, timerFrequencyInMs);
+    }
+
+    void removeIdleCallbackForNativeIdle(IdleCallback* const cb)
+    {
+        uiData->window->removeIdleCallback(cb);
+    }
+   #endif
+  #endif
+
+    // -------------------------------------------------------------------
+
+    void setWindowOffset(const int x, const int y)
+    {
+       #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        // TODO
+        (void)x; (void)y;
+       #else
+        uiData->window->setOffset(x, y);
+       #endif
+    }
+
+   #if defined(DISTRHO_PLUGIN_TARGET_VST3) || defined(DISTRHO_PLUGIN_TARGET_CLAP)
+    void setWindowSizeFromHost(const uint width, const uint height)
+    {
+       #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        ui->setSize(width, height);
+       #else
+        uiData->window->setSizeFromHost(width, height);
+       #endif
+    }
+   #endif
+
+    void setWindowTitle(const char* const uiTitle)
+    {
+        uiData->window->setTitle(uiTitle);
+    }
+
+    void setWindowTransientWinId(const uintptr_t transientParentWindowHandle)
+    {
+#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+        ui->setTransientWindowId(transientParentWindowHandle);
+#else
+        uiData->window->setTransientParent(transientParentWindowHandle);
+#endif
+    }
+
+    bool setWindowVisible(const bool yesNo)
+    {
+        uiData->window->setVisible(yesNo);
+
+        return ! uiData->app.isQuitting();
+    }
+
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+    bool handlePluginKeyboardVST(const bool press, const bool special, const uint keychar, const uint keycode, const uint16_t mods)
+    {
+        using namespace DGL_NAMESPACE;
+
+        Widget::KeyboardEvent ev;
+        ev.mod     = mods;
+        ev.press   = press;
+        ev.key     = keychar;
+        ev.keycode = keycode;
+
+        // keyboard events must always be lowercase
+        if (ev.key >= 'A' && ev.key <= 'Z')
+            ev.key += 'a' - 'A'; // A-Z -> a-z
+
+        const bool ret = ui->onKeyboard(ev);
+
+        if (press && !special && (mods & (kModifierControl|kModifierAlt|kModifierSuper)) == 0)
+        {
+            Widget::CharacterInputEvent cev;
+            cev.mod       = mods;
+            cev.character = keychar;
+            cev.keycode   = keycode;
+
+            // if shift modifier is on, convert a-z -> A-Z for character input
+            if (cev.character >= 'a' && cev.character <= 'z' && (mods & kModifierShift) != 0)
+                cev.character -= 'a' - 'A';
+
+            ui->onCharacterInput(cev);
+        }
+
+        return ret;
+    }
+#endif
+
+    // -------------------------------------------------------------------
+
+    void notifyScaleFactorChanged(const double scaleFactor)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+        ui->uiScaleFactorChanged(scaleFactor);
+    }
+
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+    void notifyFocusChanged(const bool focus)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+
+        ui->uiFocus(focus, DGL_NAMESPACE::kCrossingNormal);
+    }
+#endif
+
+    void setSampleRate(const double sampleRate, const bool doCallback = false)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
+        DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,);
+        DISTRHO_SAFE_ASSERT(sampleRate > 0.0);
+
+        if (d_isEqual(uiData->sampleRate, sampleRate))
+            return;
+
+        uiData->sampleRate = sampleRate;
+
+        if (doCallback)
+            ui->sampleRateChanged(sampleRate);
+    }
+
+    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter)
+};
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
+
+#endif // DISTRHO_UI_INTERNAL_HPP_INCLUDED