Skip to content

Commit

Permalink
Implement VST3 zoom
Browse files Browse the repository at this point in the history
VST3 zoom is very similar to VST2 zoom since both rely on
VSTGUI (and the associated bugs therein), but differ on the approach
to notify the host. The primary difference in notifying the host
is requiring a reference to the Steinberg::IPlugFrame frame class,
which has to be publically exposed to allow the processor to see it.
(This may be indicative of issues still with us choosing to not have
a formal processor/editor split, as mentioned in surge-synthesizer#164). Regardless,
once the IPlugFrame is exposed, we can use the resizeView() API
in vst3 to inform hosts in our zoom callback, as implemented here.
  • Loading branch information
baconpaul committed Jan 28, 2019
1 parent eb31ce4 commit dec0772
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 3 deletions.
13 changes: 13 additions & 0 deletions build-osx.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Commands are:
--build-and-install Build and install the assets
--build-validate-au Build and install the audio unit then validate it
--build-install-vst2 Build and install only the VST2
--build-install-vst3 Build and install only the VST3
--package Creates a .pkg file from current built state in products
--clean-and-package Cleans everything; runs all the builds; makes an installer; drops it in products
Expand Down Expand Up @@ -214,6 +215,15 @@ run_build_install_vst2()
rsync -r --delete "products/Surge.vst/" ~/Library/Audio/Plug-Ins/VST/Surge.vst/
}

run_build_install_vst3()
{
run_premake_if
run_build "vst3"

rsync -r "resources/data/" "$HOME/Library/Application Support/Surge/"
rsync -r --delete "products/Surge.vst3/" ~/Library/Audio/Plug-Ins/VST3/Surge.vst3/
}

run_clean_builds()
{
if [ ! -d "Surge.xcworkspace" ]; then
Expand Down Expand Up @@ -307,6 +317,9 @@ case $command in
--build-install-vst2)
run_build_install_vst2
;;
--build-install-vst3)
run_build_install_vst3
;;
--clean)
run_clean_builds
;;
Expand Down
13 changes: 11 additions & 2 deletions src/common/gui/SurgeGUIEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2433,12 +2433,21 @@ void SurgeGUIEditor::setZoomFactor(int zf)
#endif

CRect screenDim = Surge::GUI::getScreenDimensions(getFrame());

#if TARGET_VST3
/*
** VST3 doesn't have this API available to it, so just assume for now
*/
float baseW = WINDOW_SIZE_X;
float baseH = WINDOW_SIZE_Y;
#else
ERect *baseUISize;
getRect (&baseUISize);

float baseW = (baseUISize->right - baseUISize->left);
float baseH = (baseUISize->top - baseUISize->bottom);

#endif

// Leave enough room for window decoration with that .9. (You can probably do .95 on mac)
if (zf != 100.0 && (
(baseW * zf / 100.0) > 0.9 * screenDim.getWidth() ||
Expand Down Expand Up @@ -2566,7 +2575,7 @@ CPoint SurgeGUIEditor::getCurrentMouseLocationCorrectedForVSTGUIBugs()
frame->getCurrentMouseLocation(where);
where = frame->localToFrame(where);

#if TARGET_VST2 && HOST_SUPPORTS_ZOOM
#if ( TARGET_VST2 || TARGET_VST3 ) && HOST_SUPPORTS_ZOOM
CGraphicsTransform vstfix = frame->getTransform().inverse();
vstfix.transform(where);
vstfix.transform(where);
Expand Down
15 changes: 14 additions & 1 deletion src/common/gui/SurgeGUIEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ class SurgeGUIEditor : public EditorType, public VSTGUI::IControlListener, publi
*/
VSTGUI::CPoint getCurrentMouseLocationCorrectedForVSTGUIBugs();

#if TARGET_VST3
public:
/**
* getIPlugFrame
*
* Amazingly, IPlugView has a setFrame( IPlugFrame ) method but
* no getter. It does, however, store the value as a protected
* variable. To collaborate for zoom, we need this reference
* in the VST Processor, so expose this function
*/
Steinberg::IPlugFrame *getIPlugFrame() { return plugFrame; }
#endif

private:
void openOrRecreateEditor();
void close_editor();
Expand Down Expand Up @@ -153,6 +166,6 @@ class SurgeGUIEditor : public EditorType, public VSTGUI::IControlListener, publi
VSTGUI::CVSTGUITimer* _idleTimer = nullptr;
};

#if ( MAC && ( TARGET_AUDIOUNIT || TARGET_VST2 ) ) || (WINDOWS && TARGET_VST2 )
#if MAC || WINDOWS
#define HOST_SUPPORTS_ZOOM 1
#endif
50 changes: 50 additions & 0 deletions src/vst3/SurgeVst3Processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "pluginterfaces/vst/ivstevents.h"
#include "pluginterfaces/base/ustring.h"

#include "CScalableBitmap.h"

using namespace Steinberg::Vst;

#define CHECK_INITIALIZED \
Expand Down Expand Up @@ -402,6 +404,8 @@ IPlugView* PLUGIN_API SurgeVst3Processor::createView(const char* name)
{
SurgeGUIEditor* editor = new SurgeGUIEditor(this, surgeInstance.get());

editor->setZoomCallback( [this](SurgeGUIEditor *e) { handleZoom(e); } );

return editor;
}
return nullptr;
Expand Down Expand Up @@ -601,3 +605,49 @@ void SurgeVst3Processor::setParameterAutomated(int externalparam, float value)
performEdit(externalparam, value);
endEdit(externalparam);
}

void SurgeVst3Processor::handleZoom(SurgeGUIEditor *e)
{
float fzf = e->getZoomFactor() / 100.0;
int newW = WINDOW_SIZE_X * fzf;
int newH = WINDOW_SIZE_Y * fzf;


VSTGUI::CFrame *frame = e->getFrame();
if(frame)
{
frame->setZoom( e->getZoomFactor() / 100.0 );

/*
** rather than calling setSize on myself as in vst2, I have to
** inform the plugin frame that I have resized wiht a reference
** to a view (which is the editor). This collaborates with
** the host to resize once the content is scaled
*/
Steinberg::IPlugFrame *ipf = e->getIPlugFrame();
if (ipf)
{
Steinberg::ViewRect vr( 0, 0, newW, newH );
ipf->resizeView( e, &vr );
}

/*
** VSTGUI has an error which is that the background bitmap doesn't get the frame transform
** applied. Simply look at cviewcontainer::drawBackgroundRect. So we have to force the background
** scale up using a backdoor API.
*/

VSTGUI::CBitmap *bg = frame->getBackground();
if(bg != NULL)
{
CScalableBitmap *sbm = dynamic_cast<CScalableBitmap *>(bg); // dynamic casts are gross but better safe
if (sbm)
{
sbm->setExtraScaleFactor( e->getZoomFactor() );
}
}

frame->setDirty( true );
frame->invalid();
}
}
2 changes: 2 additions & 0 deletions src/vst3/SurgeVst3Processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,7 @@ class SurgeVst3Processor : public Steinberg::Vst::SingleComponentEffect //, publ
std::vector<SurgeGUIEditor*> viewsArray;
int blockpos;

void handleZoom(SurgeGUIEditor *e);

FpuState _fpuState;
};

0 comments on commit dec0772

Please sign in to comment.