From 1773019ca1d6748a7d735b0b229d32273979659d Mon Sep 17 00:00:00 2001 From: scheffle Date: Sat, 18 Nov 2023 17:38:43 +0100 Subject: [PATCH] add aspect ratio scalable vst3 editor class --- vstgui/plugin-bindings/vst3editor.cpp | 98 +++++++++++++++++++++++++-- vstgui/plugin-bindings/vst3editor.h | 34 +++++++++- 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/vstgui/plugin-bindings/vst3editor.cpp b/vstgui/plugin-bindings/vst3editor.cpp index 9ac05d1d0..34ca87ec8 100644 --- a/vstgui/plugin-bindings/vst3editor.cpp +++ b/vstgui/plugin-bindings/vst3editor.cpp @@ -561,9 +561,15 @@ bool VST3Editor::setEditorSizeConstrains (const CPoint& newMinimumSize, const CP //----------------------------------------------------------------------------- double VST3Editor::getAbsScaleFactor () const { - return zoomFactor * contentScaleFactor; + return getZoomFactor () * getContentScaleFactor (); } +//----------------------------------------------------------------------------- +double VST3Editor::getContentScaleFactor () const { return contentScaleFactor; } + +//----------------------------------------------------------------------------- +double VST3Editor::getZoomFactor () const { return zoomFactor; } + #ifdef VST3_CONTENT_SCALE_SUPPORT //----------------------------------------------------------------------------- Steinberg::tresult PLUGIN_API VST3Editor::setContentScaleFactor (ScaleFactor factor) @@ -580,7 +586,7 @@ Steinberg::tresult PLUGIN_API VST3Editor::setContentScaleFactor (ScaleFactor fac //----------------------------------------------------------------------------- void VST3Editor::setZoomFactor (double factor) { - if (zoomFactor == factor) + if (getZoomFactor () == factor) return; zoomFactor = factor; @@ -861,7 +867,7 @@ void VST3Editor::onMouseEvent (MouseEvent& event, CFrame* frame) static_cast ((*it) * 100)); CMenuItem* item = zoomMenu->addEntry (new CCommandMenuItem ( {zoomFactorString, zoomFactorTag, this, "Zoom", zoomFactorString})); - if (zoomFactor == *it) + if (getZoomFactor () == *it) item->setChecked (true); } CMenuItem* item = controllerMenu->addEntry ("UI Zoom"); @@ -1072,6 +1078,9 @@ void VST3Editor::requestRecreateView () } } +//----------------------------------------------------------------------------- +bool VST3Editor::inEditMode () const { return editingEnabled; } + #if LINUX // Map Steinberg Vst Interface to VSTGUI Interface class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted @@ -1891,7 +1900,7 @@ bool VST3Editor::enableEditing (bool state) getFrame ()->setSize (width, height); getFrame ()->addView (view); - getFrame()->setZoom (contentScaleFactor); + getFrame ()->setZoom (getContentScaleFactor ()); getFrame ()->enableTooltips (true); CColor focusColor = kBlueCColor; @@ -2046,5 +2055,86 @@ UIDescription* VST3Editor::getUIDescription () const return description; } +//------------------------------------------------------------------------ +//--- AspectRatioVST3Editor +//------------------------------------------------------------------------ +void AspectRatioVST3Editor::setMinZoomFactor (double factor) { minZoomFactor = factor; } + +//------------------------------------------------------------------------ +double AspectRatioVST3Editor::getMinZoomFactor () const { return minZoomFactor; } + +//------------------------------------------------------------------------ +bool PLUGIN_API AspectRatioVST3Editor::open (void* parent, const PlatformType& type) +{ + if (VST3Editor::open (parent, type) && getFrame ()) + { + initialSize = getFrame ()->getViewSize ().getSize (); + calcZoomFactor = getZoomFactor (); + return true; + } + return false; +} + +//------------------------------------------------------------------------ +Steinberg::tresult PLUGIN_API AspectRatioVST3Editor::onSize (Steinberg::ViewRect* newSize) +{ + if (newSize == nullptr) + return Steinberg::kInvalidArgument; + + if (!canCalculateAspectRatio ()) + return VST3Editor::onSize (newSize); + + setZoomFactor (calcZoomFactor); + return Steinberg::kResultTrue; +} + +//------------------------------------------------------------------------ +Steinberg::tresult PLUGIN_API AspectRatioVST3Editor::checkSizeConstraint (Steinberg::ViewRect* rect) +{ + if (rect == nullptr) + return Steinberg::kInvalidArgument; + + if (!canCalculateAspectRatio ()) + return VST3Editor::checkSizeConstraint (rect); + + const CPoint size (rect->getWidth (), rect->getHeight ()); + auto diff = size - initialSize; + auto anchor = initialSize.x >= initialSize.y ? initialSize.x : initialSize.y; + auto sizeAnchor = initialSize.x >= initialSize.y ? size.x : size.y; + + auto factor = sizeAnchor / anchor; + if (factor < minZoomFactor * getContentScaleFactor ()) + factor = minZoomFactor * getContentScaleFactor (); + factor = std::round (factor * anchor) / anchor; + auto newSize = initialSize * factor; + calcZoomFactor = factor / getContentScaleFactor (); + if (newSize != size) + { + rect->right = rect->left + newSize.x; + rect->bottom = rect->top + newSize.y; + } + return Steinberg::kResultTrue; +} + +#ifdef VST3_CONTENT_SCALE_SUPPORT +//------------------------------------------------------------------------ +Steinberg::tresult PLUGIN_API AspectRatioVST3Editor::setContentScaleFactor (ScaleFactor factor) +{ + auto res = VST3Editor::setContentScaleFactor (factor); + if (res == Steinberg::kResultTrue) + setZoomFactor (calcZoomFactor); + return res; +} +#endif + +//------------------------------------------------------------------------ +bool AspectRatioVST3Editor::canCalculateAspectRatio () const +{ + auto f = getFrame (); + if (inEditMode () || (f && f->hasChildren () == false)) + return false; + return true; +} + //------------------------------------------------------------------------ } // VSTGUI diff --git a/vstgui/plugin-bindings/vst3editor.h b/vstgui/plugin-bindings/vst3editor.h index b653a8aad..2eea845ef 100644 --- a/vstgui/plugin-bindings/vst3editor.h +++ b/vstgui/plugin-bindings/vst3editor.h @@ -125,8 +125,8 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, bool requestResize (const CPoint& newSize); void setZoomFactor (double factor); - double getZoomFactor () const { return zoomFactor; } - + double getZoomFactor () const; + void setAllowedZoomFactors (std::vector zoomFactors) { allowedZoomFactors = zoomFactors; } /** set the delegate of the editor. no reference counting is happening here. */ @@ -141,6 +141,7 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, ~VST3Editor () override; void init (); double getAbsScaleFactor () const; + double getContentScaleFactor () const; ParameterChangeListener* getParameterChangeListener (int32_t tag) const; void recreateView (); void requestRecreateView (); @@ -152,6 +153,7 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, bool enableShowEditButton () const; void enableShowEditButton (bool state); void showEditButton (bool state); + bool inEditMode () const; bool PLUGIN_API open (void* parent, const PlatformType& type) override; void PLUGIN_API close () override; @@ -221,5 +223,33 @@ class VST3Editor : public Steinberg::Vst::VSTGUIEditor, Optional sizeRequest; }; +//----------------------------------------------------------------------------- +//! @brief An extended VST3 Editor which scales its contents when resized +//! @ingroup new_in_4_14 +//----------------------------------------------------------------------------- +class AspectRatioVST3Editor : public VST3Editor +{ +public: + using VST3Editor::VST3Editor; + + void setMinZoomFactor (double factor); + double getMinZoomFactor () const; + +protected: + bool canCalculateAspectRatio () const; + + bool PLUGIN_API open (void* parent, const PlatformType& type) override; + Steinberg::tresult PLUGIN_API onSize (Steinberg::ViewRect* newSize) override; + Steinberg::tresult PLUGIN_API checkSizeConstraint (Steinberg::ViewRect* rect) override; +#ifdef VST3_CONTENT_SCALE_SUPPORT + Steinberg::tresult PLUGIN_API setContentScaleFactor (ScaleFactor factor) override; +#endif + +private: + CPoint initialSize {}; + double minZoomFactor {1.}; + double calcZoomFactor {1.}; +}; + //------------------------------------------------------------------------ } // VSTGUI