diff DPF-Prymula-audioplugins/dpf/dgl/src/Window.cpp @ 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/dgl/src/Window.cpp	Mon Oct 16 21:53:34 2023 +0200
@@ -0,0 +1,546 @@
+/*
+ * 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.
+ */
+
+#include "WindowPrivateData.hpp"
+#include "../TopLevelWidget.hpp"
+
+#include "pugl.hpp"
+
+START_NAMESPACE_DGL
+
+// -----------------------------------------------------------------------
+// ScopedGraphicsContext
+
+Window::ScopedGraphicsContext::ScopedGraphicsContext(Window& win)
+    : window(win),
+      ppData(nullptr),
+      active(puglBackendEnter(window.pData->view)),
+      reenter(false) {}
+
+Window::ScopedGraphicsContext::ScopedGraphicsContext(Window& win, Window& transientWin)
+    : window(win),
+      ppData(transientWin.pData),
+      active(false),
+      reenter(true)
+{
+    puglBackendLeave(ppData->view);
+    active = puglBackendEnter(window.pData->view);
+}
+
+Window::ScopedGraphicsContext::~ScopedGraphicsContext()
+{
+    done();
+}
+
+void Window::ScopedGraphicsContext::done()
+{
+    if (active)
+    {
+        puglBackendLeave(window.pData->view);
+        active = false;
+    }
+
+    if (reenter)
+    {
+        reenter = false;
+        DISTRHO_SAFE_ASSERT_RETURN(ppData != nullptr,);
+
+        puglBackendEnter(ppData->view);
+    }
+}
+
+void Window::ScopedGraphicsContext::reinit()
+{
+    DISTRHO_SAFE_ASSERT_RETURN(!active,);
+    DISTRHO_SAFE_ASSERT_RETURN(!reenter,);
+    DISTRHO_SAFE_ASSERT_RETURN(ppData != nullptr,);
+
+    reenter = true;
+    puglBackendLeave(ppData->view);
+    active = puglBackendEnter(window.pData->view);
+}
+
+// -----------------------------------------------------------------------
+// Window
+
+Window::Window(Application& app)
+    : pData(new PrivateData(app, this))
+{
+    pData->initPost();
+}
+
+Window::Window(Application& app, Window& transientParentWindow)
+    : pData(new PrivateData(app, this, transientParentWindow.pData))
+{
+    pData->initPost();
+}
+
+Window::Window(Application& app,
+               const uintptr_t parentWindowHandle,
+               const double scaleFactor,
+               const bool resizable)
+    : pData(new PrivateData(app, this, parentWindowHandle, scaleFactor, resizable))
+{
+    pData->initPost();
+}
+
+Window::Window(Application& app,
+               const uintptr_t parentWindowHandle,
+               const uint width,
+               const uint height,
+               const double scaleFactor,
+               const bool resizable)
+    : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, false))
+{
+    pData->initPost();
+}
+
+Window::Window(Application& app,
+               const uintptr_t parentWindowHandle,
+               const uint width,
+               const uint height,
+               const double scaleFactor,
+               const bool resizable,
+               const bool isVST3,
+               const bool doPostInit)
+    : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, isVST3))
+{
+    if (doPostInit)
+        pData->initPost();
+}
+
+Window::~Window()
+{
+    delete pData;
+}
+
+bool Window::isEmbed() const noexcept
+{
+    return pData->isEmbed;
+}
+
+bool Window::isVisible() const noexcept
+{
+    return pData->isVisible;
+}
+
+void Window::setVisible(const bool visible)
+{
+    if (visible)
+        pData->show();
+    else
+        pData->hide();
+}
+
+void Window::show()
+{
+    pData->show();
+}
+
+void Window::hide()
+{
+    pData->hide();
+}
+
+void Window::close()
+{
+    pData->close();
+}
+
+bool Window::isResizable() const noexcept
+{
+    return puglGetViewHint(pData->view, PUGL_RESIZABLE) == PUGL_TRUE;
+}
+
+void Window::setResizable(const bool resizable)
+{
+    pData->setResizable(resizable);
+}
+
+int Window::getOffsetX() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0);
+
+    return puglGetFrame(pData->view).x;
+}
+
+int Window::getOffsetY() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0);
+
+    return puglGetFrame(pData->view).y;
+}
+
+Point<int> Window::getOffset() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, Point<int>());
+
+    const PuglRect rect = puglGetFrame(pData->view);
+    return Point<int>(rect.x, rect.y);
+}
+
+void Window::setOffsetX(const int x)
+{
+    setOffset(x, getOffsetY());
+}
+
+void Window::setOffsetY(const int y)
+{
+    setOffset(getOffsetX(), y);
+}
+
+void Window::setOffset(const int x, const int y)
+{
+    puglSetPosition(pData->view, x, y);
+}
+
+void Window::setOffset(const Point<int>& offset)
+{
+    setOffset(offset.getX(), offset.getY());
+}
+
+uint Window::getWidth() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0);
+
+    const double width = puglGetFrame(pData->view).width;
+    DISTRHO_SAFE_ASSERT_RETURN(width >= 0.0, 0);
+    return static_cast<uint>(width + 0.5);
+}
+
+uint Window::getHeight() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0);
+
+    const double height = puglGetFrame(pData->view).height;
+    DISTRHO_SAFE_ASSERT_RETURN(height >= 0.0, 0);
+    return static_cast<uint>(height + 0.5);
+}
+
+Size<uint> Window::getSize() const noexcept
+{
+    DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, Size<uint>());
+
+    const PuglRect rect = puglGetFrame(pData->view);
+    DISTRHO_SAFE_ASSERT_RETURN(rect.width >= 0.0, Size<uint>());
+    DISTRHO_SAFE_ASSERT_RETURN(rect.height >= 0.0, Size<uint>());
+    return Size<uint>(static_cast<uint>(rect.width + 0.5),
+                      static_cast<uint>(rect.height + 0.5));
+}
+
+void Window::setWidth(const uint width)
+{
+    setSize(width, getHeight());
+}
+
+void Window::setHeight(const uint height)
+{
+    setSize(getWidth(), height);
+}
+
+void Window::setSize(uint width, uint height)
+{
+    DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,);
+
+    if (pData->isEmbed)
+    {
+        const double scaleFactor = pData->scaleFactor;
+        uint minWidth = pData->minWidth;
+        uint minHeight = pData->minHeight;
+
+        if (pData->autoScaling && scaleFactor != 1.0)
+        {
+            minWidth *= scaleFactor;
+            minHeight *= scaleFactor;
+        }
+
+        // handle geometry constraints here
+        if (width < minWidth)
+            width = minWidth;
+
+        if (height < minHeight)
+            height = minHeight;
+
+        if (pData->keepAspectRatio)
+        {
+            const double ratio = static_cast<double>(pData->minWidth)
+                               / static_cast<double>(pData->minHeight);
+            const double reqRatio = static_cast<double>(width)
+                                  / static_cast<double>(height);
+
+            if (d_isNotEqual(ratio, reqRatio))
+            {
+                // fix width
+                if (reqRatio > ratio)
+                    width = static_cast<uint>(height * ratio + 0.5);
+                // fix height
+                else
+                    height = static_cast<uint>(static_cast<double>(width) / ratio + 0.5);
+            }
+        }
+    }
+
+    if (pData->usesSizeRequest)
+    {
+        DISTRHO_SAFE_ASSERT_RETURN(pData->topLevelWidgets.size() != 0,);
+
+        TopLevelWidget* const topLevelWidget = pData->topLevelWidgets.front();
+        DISTRHO_SAFE_ASSERT_RETURN(topLevelWidget != nullptr,);
+
+        topLevelWidget->requestSizeChange(width, height);
+    }
+    else
+    {
+        puglSetSizeAndDefault(pData->view, width, height);
+    }
+}
+
+void Window::setSize(const Size<uint>& size)
+{
+    setSize(size.getWidth(), size.getHeight());
+}
+
+const char* Window::getTitle() const noexcept
+{
+    return puglGetWindowTitle(pData->view);
+}
+
+void Window::setTitle(const char* const title)
+{
+    if (pData->view != nullptr)
+        puglSetWindowTitle(pData->view, title);
+}
+
+bool Window::isIgnoringKeyRepeat() const noexcept
+{
+    return puglGetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT) == PUGL_TRUE;
+}
+
+void Window::setIgnoringKeyRepeat(const bool ignore) noexcept
+{
+    puglSetViewHint(pData->view, PUGL_IGNORE_KEY_REPEAT, ignore);
+}
+
+const void* Window::getClipboard(size_t& dataSize)
+{
+    return pData->getClipboard(dataSize);
+}
+
+bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
+{
+    return puglSetClipboard(pData->view, mimeType != nullptr ? mimeType : "text/plain", data, dataSize) == PUGL_SUCCESS;
+}
+
+bool Window::setCursor(const MouseCursor cursor)
+{
+    return puglSetCursor(pData->view, static_cast<PuglCursor>(cursor)) == PUGL_SUCCESS;
+}
+
+bool Window::addIdleCallback(IdleCallback* const callback, const uint timerFrequencyInMs)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr, false)
+
+    return pData->addIdleCallback(callback, timerFrequencyInMs);
+}
+
+bool Window::removeIdleCallback(IdleCallback* const callback)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr, false)
+
+    return pData->removeIdleCallback(callback);
+}
+
+Application& Window::getApp() const noexcept
+{
+    return pData->app;
+}
+
+#ifndef DPF_TEST_WINDOW_CPP
+const GraphicsContext& Window::getGraphicsContext() const noexcept
+{
+    return pData->getGraphicsContext();
+}
+#endif
+
+uintptr_t Window::getNativeWindowHandle() const noexcept
+{
+    return puglGetNativeView(pData->view);
+}
+
+double Window::getScaleFactor() const noexcept
+{
+    return pData->scaleFactor;
+}
+
+void Window::focus()
+{
+    pData->focus();
+}
+
+#ifndef DGL_FILE_BROWSER_DISABLED
+bool Window::openFileBrowser(const FileBrowserOptions& options)
+{
+    return pData->openFileBrowser(options);
+}
+#endif
+
+void Window::repaint() noexcept
+{
+    if (pData->view == nullptr)
+        return;
+
+    puglPostRedisplay(pData->view);
+}
+
+void Window::repaint(const Rectangle<uint>& rect) noexcept
+{
+    if (pData->view == nullptr)
+        return;
+
+    PuglRect prect = {
+        static_cast<PuglCoord>(rect.getX()),
+        static_cast<PuglCoord>(rect.getY()),
+        static_cast<PuglSpan>(rect.getWidth()),
+        static_cast<PuglSpan>(rect.getHeight()),
+    };
+    if (pData->autoScaling)
+    {
+        const double autoScaleFactor = pData->autoScaleFactor;
+
+        prect.x *= autoScaleFactor;
+        prect.y *= autoScaleFactor;
+        prect.width *= autoScaleFactor;
+        prect.height *= autoScaleFactor;
+    }
+    puglPostRedisplayRect(pData->view, prect);
+}
+
+void Window::renderToPicture(const char* const filename)
+{
+    pData->filenameToRenderInto = strdup(filename);
+}
+
+void Window::runAsModal(bool blockWait)
+{
+    pData->runAsModal(blockWait);
+}
+
+Size<uint> Window::getGeometryConstraints(bool& keepAspectRatio)
+{
+    keepAspectRatio = pData->keepAspectRatio;
+    return Size<uint>(pData->minWidth, pData->minHeight);
+}
+
+void Window::setGeometryConstraints(uint minimumWidth,
+                                    uint minimumHeight,
+                                    const bool keepAspectRatio,
+                                    const bool automaticallyScale,
+                                    const bool resizeNowIfAutoScaling)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,);
+    DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,);
+
+    pData->minWidth = minimumWidth;
+    pData->minHeight = minimumHeight;
+    pData->autoScaling = automaticallyScale;
+    pData->keepAspectRatio = keepAspectRatio;
+
+    if (pData->view == nullptr)
+        return;
+
+    const double scaleFactor = pData->scaleFactor;
+
+    if (automaticallyScale && scaleFactor != 1.0)
+    {
+        minimumWidth *= scaleFactor;
+        minimumHeight *= scaleFactor;
+    }
+
+    puglSetGeometryConstraints(pData->view, minimumWidth, minimumHeight, keepAspectRatio);
+
+    if (scaleFactor != 1.0 && automaticallyScale && resizeNowIfAutoScaling)
+    {
+        const Size<uint> size(getSize());
+
+        setSize(static_cast<uint>(size.getWidth() * scaleFactor + 0.5),
+                static_cast<uint>(size.getHeight() * scaleFactor + 0.5));
+    }
+}
+
+void Window::setTransientParent(const uintptr_t transientParentWindowHandle)
+{
+    puglSetTransientParent(pData->view, transientParentWindowHandle);
+}
+
+std::vector<ClipboardDataOffer> Window::getClipboardDataOfferTypes()
+{
+    std::vector<ClipboardDataOffer> offerTypes;
+
+    if (const uint32_t numTypes = puglGetNumClipboardTypes(pData->view))
+    {
+        offerTypes.reserve(numTypes);
+
+        for (uint32_t i=0; i<numTypes; ++i)
+        {
+            const ClipboardDataOffer offer = { i + 1, puglGetClipboardType(pData->view, i) };
+            offerTypes.push_back(offer);
+        }
+    }
+
+    return offerTypes;
+}
+
+uint32_t Window::onClipboardDataOffer()
+{
+    std::vector<ClipboardDataOffer> offers(getClipboardDataOfferTypes());
+
+    for (std::vector<ClipboardDataOffer>::iterator it=offers.begin(), end=offers.end(); it != end;++it)
+    {
+        const ClipboardDataOffer offer = *it;
+        if (std::strcmp(offer.type, "text/plain") == 0)
+            return offer.id;
+    }
+
+    return 0;
+}
+
+bool Window::onClose()
+{
+    return true;
+}
+
+void Window::onFocus(bool, CrossingMode)
+{
+}
+
+void Window::onReshape(uint, uint)
+{
+    puglFallbackOnResize(pData->view);
+}
+
+void Window::onScaleFactorChanged(double)
+{
+}
+
+#ifndef DGL_FILE_BROWSER_DISABLED
+void Window::onFileSelected(const char*)
+{
+}
+#endif
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DGL