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