Mercurial > hg > pub > prymula > com
view 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 source
/* * 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