Signed-off-by: falkTX <falktx@falktx.com>pull/357/head
| @@ -110,7 +110,8 @@ public: | |||
| void setGeometryConstraints(uint minimumWidth, | |||
| uint minimumHeight, | |||
| bool keepAspectRatio = false, | |||
| bool automaticallyScale = false); | |||
| bool automaticallyScale = false, | |||
| bool resizeNowIfAutoScaling = true); | |||
| DISTRHO_DEPRECATED_BY("getApp()") | |||
| Application& getParentApp() const noexcept { return getApp(); } | |||
| @@ -132,6 +133,8 @@ private: | |||
| #ifdef DISTRHO_DEFINES_H_INCLUDED | |||
| friend class DISTRHO_NAMESPACE::UI; | |||
| #endif | |||
| /** @internal */ | |||
| virtual void requestSizeChange(uint width, uint height); | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopLevelWidget) | |||
| }; | |||
| @@ -399,7 +399,8 @@ public: | |||
| void setGeometryConstraints(uint minimumWidth, | |||
| uint minimumHeight, | |||
| bool keepAspectRatio = false, | |||
| bool automaticallyScale = false); | |||
| bool automaticallyScale = false, | |||
| bool resizeNowIfAutoScaling = true); | |||
| /** DEPRECATED Use isIgnoringKeyRepeat(). */ | |||
| DISTRHO_DEPRECATED_BY("isIgnoringKeyRepeat()") | |||
| @@ -473,6 +474,7 @@ private: | |||
| uint height, | |||
| double scaleFactor, | |||
| bool resizable, | |||
| bool isVST3, | |||
| bool doPostInit); | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window); | |||
| @@ -60,7 +60,7 @@ void TopLevelWidget::setSize(const Size<uint>& size) | |||
| pData->window.setSize(size); | |||
| } | |||
| bool TopLevelWidget::setClipboard(const char* mimeType, const void* data, size_t dataSize) | |||
| bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize) | |||
| { | |||
| return pData->window.setClipboard(mimeType, data, dataSize); | |||
| } | |||
| @@ -103,9 +103,14 @@ void TopLevelWidget::repaint(const Rectangle<uint>& rect) noexcept | |||
| void TopLevelWidget::setGeometryConstraints(const uint minimumWidth, | |||
| const uint minimumHeight, | |||
| const bool keepAspectRatio, | |||
| const bool automaticallyScale) | |||
| const bool automaticallyScale, | |||
| const bool resizeNowIfAutoScaling) | |||
| { | |||
| pData->window.setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale); | |||
| pData->window.setGeometryConstraints(minimumWidth, | |||
| minimumHeight, | |||
| keepAspectRatio, | |||
| automaticallyScale, | |||
| resizeNowIfAutoScaling); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -137,4 +142,10 @@ bool TopLevelWidget::onScroll(const ScrollEvent& ev) | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void TopLevelWidget::requestSizeChange(uint, uint) | |||
| { | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -30,7 +30,7 @@ struct TopLevelWidget::PrivateData { | |||
| Widget* const selfw; | |||
| Window& window; | |||
| explicit PrivateData(TopLevelWidget* const s, Window& w); | |||
| explicit PrivateData(TopLevelWidget* self, Window& window); | |||
| ~PrivateData(); | |||
| void display(); | |||
| bool keyboardEvent(const KeyboardEvent& ev); | |||
| @@ -15,6 +15,7 @@ | |||
| */ | |||
| #include "WindowPrivateData.hpp" | |||
| #include "../TopLevelWidget.hpp" | |||
| #include "pugl.hpp" | |||
| @@ -87,7 +88,7 @@ Window::Window(Application& app, | |||
| const uint height, | |||
| const double scaleFactor, | |||
| const bool resizable) | |||
| : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable)) | |||
| : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, false)) | |||
| { | |||
| pData->initPost(); | |||
| } | |||
| @@ -98,8 +99,9 @@ Window::Window(Application& app, | |||
| 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)) | |||
| : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, isVST3)) | |||
| { | |||
| if (doPostInit) | |||
| pData->initPost(); | |||
| @@ -228,7 +230,19 @@ void Window::setSize(uint width, uint height) | |||
| } | |||
| } | |||
| puglSetWindowSize(pData->view, width, height); | |||
| 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 | |||
| { | |||
| puglSetWindowSize(pData->view, width, height); | |||
| } | |||
| } | |||
| void Window::setSize(const Size<uint>& size) | |||
| @@ -371,10 +385,11 @@ Size<uint> Window::getGeometryConstraints(bool& keepAspectRatio) | |||
| return Size<uint>(pData->minWidth, pData->minHeight); | |||
| } | |||
| void Window::setGeometryConstraints(const uint minimumWidth, | |||
| const uint minimumHeight, | |||
| void Window::setGeometryConstraints(uint minimumWidth, | |||
| uint minimumHeight, | |||
| const bool keepAspectRatio, | |||
| const bool automaticallyScale) | |||
| const bool automaticallyScale, | |||
| const bool resizeNowIfAutoScaling) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,); | |||
| @@ -389,12 +404,15 @@ void Window::setGeometryConstraints(const uint minimumWidth, | |||
| const double scaleFactor = pData->scaleFactor; | |||
| puglSetGeometryConstraints(pData->view, | |||
| static_cast<uint>(minimumWidth * scaleFactor + 0.5), | |||
| static_cast<uint>(minimumHeight * scaleFactor + 0.5), | |||
| keepAspectRatio); | |||
| if (automaticallyScale && scaleFactor != 1.0) | |||
| { | |||
| minimumWidth *= scaleFactor; | |||
| minimumHeight *= scaleFactor; | |||
| } | |||
| puglSetGeometryConstraints(pData->view, minimumWidth, minimumHeight, keepAspectRatio); | |||
| if (scaleFactor != 1.0) | |||
| if (scaleFactor != 1.0 && automaticallyScale && resizeNowIfAutoScaling) | |||
| { | |||
| const Size<uint> size(getSize()); | |||
| @@ -76,6 +76,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) | |||
| isClosed(true), | |||
| isVisible(false), | |||
| isEmbed(false), | |||
| usesSizeRequest(false), | |||
| scaleFactor(getDesktopScaleFactor(view)), | |||
| autoScaling(false), | |||
| autoScaleFactor(1.0), | |||
| @@ -103,6 +104,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c | |||
| isClosed(true), | |||
| isVisible(false), | |||
| isEmbed(false), | |||
| usesSizeRequest(false), | |||
| scaleFactor(ppData->scaleFactor), | |||
| autoScaling(false), | |||
| autoScaleFactor(1.0), | |||
| @@ -134,6 +136,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
| isClosed(parentWindowHandle == 0), | |||
| isVisible(parentWindowHandle != 0), | |||
| isEmbed(parentWindowHandle != 0), | |||
| usesSizeRequest(false), | |||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||
| autoScaling(false), | |||
| autoScaleFactor(1.0), | |||
| @@ -157,7 +160,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
| Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
| const uintptr_t parentWindowHandle, | |||
| const uint width, const uint height, | |||
| const double scale, const bool resizable) | |||
| const double scale, const bool resizable, const bool isVST3) | |||
| : app(a), | |||
| appData(a.pData), | |||
| self(s), | |||
| @@ -167,6 +170,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
| isClosed(parentWindowHandle == 0), | |||
| isVisible(parentWindowHandle != 0 && view != nullptr), | |||
| isEmbed(parentWindowHandle != 0), | |||
| usesSizeRequest(isVST3), | |||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||
| autoScaling(false), | |||
| autoScaleFactor(1.0), | |||
| @@ -63,6 +63,9 @@ struct Window::PrivateData : IdleCallback { | |||
| /** Whether this Window is embed into another (usually not DGL-controlled) Window. */ | |||
| const bool isEmbed; | |||
| /** Whether to ignore resize requests and feed them into the host instead. used for VST3 */ | |||
| const bool usesSizeRequest; | |||
| /** Scale factor to report to widgets on request, purely informational. */ | |||
| double scaleFactor; | |||
| @@ -127,7 +130,7 @@ struct Window::PrivateData : IdleCallback { | |||
| /** Constructor for an embed Window, with a few extra hints from the host side. */ | |||
| explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle, | |||
| uint width, uint height, double scaling, bool resizable); | |||
| uint width, uint height, double scaling, bool resizable, bool isVST3); | |||
| /** Destructor. */ | |||
| ~PrivateData() override; | |||
| @@ -84,7 +84,7 @@ public: | |||
| It assumes aspect ratio is meant to be kept. | |||
| Manually call setGeometryConstraints instead if keeping UI aspect ratio is not required. | |||
| */ | |||
| UI(uint width = 0, uint height = 0, bool automaticallyScale = false); | |||
| UI(uint width = 0, uint height = 0, bool automaticallyScaleAndSetAsMinimumSize = false); | |||
| /** | |||
| Destructor. | |||
| @@ -358,6 +358,10 @@ private: | |||
| PrivateData* const uiData; | |||
| friend class DGL_NAMESPACE::PluginWindow; | |||
| friend class UIExporter; | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| /** @internal */ | |||
| void requestSizeChange(uint width, uint height) override; | |||
| #endif | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | |||
| }; | |||
| @@ -189,21 +189,21 @@ UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint hei | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * UI */ | |||
| UI::UI(const uint width, const uint height, const bool automaticallyScale) | |||
| UI::UI(const uint width, const uint height, const bool automaticallyScaleAndSetAsMinimumSize) | |||
| : UIWidget(UI::PrivateData::createNextWindow(this, width, height)), | |||
| uiData(UI::PrivateData::s_nextPrivateData) | |||
| { | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| if (width > 0 && height > 0) | |||
| if (width != 0 && height != 0) | |||
| { | |||
| Widget::setSize(width, height); | |||
| if (automaticallyScale) | |||
| if (automaticallyScaleAndSetAsMinimumSize) | |||
| setGeometryConstraints(width, height, true, true); | |||
| } | |||
| #else | |||
| // unused | |||
| return; (void)automaticallyScale; | |||
| (void)automaticallyScaleAndSetAsMinimumSize; | |||
| #endif | |||
| } | |||
| @@ -370,9 +370,20 @@ void UI::onResize(const ResizeEvent& ev) | |||
| { | |||
| UIWidget::onResize(ev); | |||
| #ifndef DISTRHO_PLUGIN_TARGET_VST3 | |||
| if (uiData->initializing) | |||
| return; | |||
| const uint width = ev.size.getWidth(); | |||
| const uint height = ev.size.getHeight(); | |||
| uiData->setSizeCallback(width, height); | |||
| #endif | |||
| } | |||
| // NOTE: only used for VST3 | |||
| void UI::requestSizeChange(const uint width, const uint height) | |||
| { | |||
| uiData->setSizeCallback(width, height); | |||
| } | |||
| #endif | |||
| @@ -98,6 +98,7 @@ public: | |||
| DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,); | |||
| ui = uiPtr; | |||
| uiData->initializing = false; | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| // unused | |||
| @@ -33,7 +33,13 @@ | |||
| # define DISTRHO_UI_IS_STANDALONE 0 | |||
| #endif | |||
| #if defined(DISTRHO_PLUGIN_TARGET_VST2) | |||
| #ifdef DISTRHO_PLUGIN_TARGET_VST3 | |||
| # define DISTRHO_UI_IS_VST3 1 | |||
| #else | |||
| # define DISTRHO_UI_IS_VST3 0 | |||
| #endif | |||
| #ifdef DISTRHO_PLUGIN_TARGET_VST2 | |||
| # undef DISTRHO_UI_USER_RESIZABLE | |||
| # define DISTRHO_UI_USER_RESIZABLE 0 | |||
| #endif | |||
| @@ -175,7 +181,8 @@ public: | |||
| const uint width, | |||
| const uint height, | |||
| const double scaleFactor) | |||
| : Window(app, parentWindowHandle, width, height, scaleFactor, DISTRHO_UI_USER_RESIZABLE, false), | |||
| : Window(app, parentWindowHandle, width, height, scaleFactor, | |||
| DISTRHO_UI_USER_RESIZABLE, DISTRHO_UI_IS_VST3, false), | |||
| ui(uiPtr), | |||
| initializing(true), | |||
| receivedReshapeDuringInit(false) | |||
| @@ -332,6 +339,9 @@ struct UI::PrivateData { | |||
| #endif | |||
| char* bundlePath; | |||
| // Ignore initial resize events while initializing | |||
| bool initializing; | |||
| // Callbacks | |||
| void* callbacksPtr; | |||
| editParamFunc editParamCallbackFunc; | |||
| @@ -355,6 +365,7 @@ struct UI::PrivateData { | |||
| uiStateFileKeyRequest(nullptr), | |||
| #endif | |||
| bundlePath(nullptr), | |||
| initializing(true), | |||
| callbacksPtr(nullptr), | |||
| editParamCallbackFunc(nullptr), | |||
| setParamCallbackFunc(nullptr), | |||