|
|
|
@@ -720,6 +720,7 @@ private: |
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
Atomic<int> vst3IsPlaying { 0 };
|
|
|
|
float lastScaleFactorReceived = 1.0f;
|
|
|
|
|
|
|
|
void setupParameters()
|
|
|
|
{
|
|
|
|
@@ -808,6 +809,8 @@ private: |
|
|
|
: Vst::EditorView (&ec, nullptr),
|
|
|
|
owner (&ec), pluginInstance (p)
|
|
|
|
{
|
|
|
|
editorScaleFactor = ec.lastScaleFactorReceived;
|
|
|
|
|
|
|
|
component.reset (new ContentWrapperComponent (*this, p));
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -853,7 +856,7 @@ private: |
|
|
|
#endif
|
|
|
|
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) scaleFactor);
|
|
|
|
setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) editorScaleFactor);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
component->resizeHostWindow();
|
|
|
|
@@ -895,10 +898,15 @@ private: |
|
|
|
|
|
|
|
if (component != nullptr)
|
|
|
|
{
|
|
|
|
auto scale = component->getNativeEditorScaleFactor();
|
|
|
|
auto w = rect.getWidth();
|
|
|
|
auto h = rect.getHeight();
|
|
|
|
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
w = roundToInt (w / editorScaleFactor);
|
|
|
|
h = roundToInt (h / editorScaleFactor);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
component->setSize (roundToInt (rect.getWidth() / scale),
|
|
|
|
roundToInt (rect.getHeight() / scale));
|
|
|
|
component->setSize (w, h);
|
|
|
|
|
|
|
|
if (auto* peer = component->getPeer())
|
|
|
|
peer->updateBounds();
|
|
|
|
@@ -915,11 +923,15 @@ private: |
|
|
|
{
|
|
|
|
if (size != nullptr && component != nullptr)
|
|
|
|
{
|
|
|
|
auto scale = component->getNativeEditorScaleFactor();
|
|
|
|
auto w = component->getWidth();
|
|
|
|
auto h = component->getHeight();
|
|
|
|
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
w = roundToInt (w * editorScaleFactor);
|
|
|
|
h = roundToInt (h * editorScaleFactor);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*size = ViewRect (0, 0,
|
|
|
|
roundToInt (component->getWidth() * scale),
|
|
|
|
roundToInt (component->getHeight() * scale));
|
|
|
|
*size = ViewRect (0, 0, w, h);
|
|
|
|
|
|
|
|
return kResultTrue;
|
|
|
|
}
|
|
|
|
@@ -942,12 +954,14 @@ private: |
|
|
|
{
|
|
|
|
if (auto* editor = component->pluginEditor.get())
|
|
|
|
{
|
|
|
|
// checkSizeConstraint
|
|
|
|
auto scale = component->getNativeEditorScaleFactor();
|
|
|
|
auto scaledRect = (Rectangle<int>::leftTopRightBottom (rectToCheck->left, rectToCheck->top,
|
|
|
|
rectToCheck->right, rectToCheck->bottom).toFloat() / scale).toNearestInt();
|
|
|
|
|
|
|
|
auto juceRect = editor->getLocalArea (component.get(), scaledRect);
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
auto juceRect = editor->getLocalArea (component.get(),
|
|
|
|
Rectangle<int>::leftTopRightBottom (rectToCheck->left, rectToCheck->top,
|
|
|
|
rectToCheck->right, rectToCheck->bottom) / editorScaleFactor);
|
|
|
|
#else
|
|
|
|
auto juceRect = editor->getLocalArea (component.get(),
|
|
|
|
{ rectToCheck->left, rectToCheck->top, rectToCheck->right, rectToCheck->bottom });
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (auto* constrainer = editor->getConstrainer())
|
|
|
|
{
|
|
|
|
@@ -963,8 +977,13 @@ private: |
|
|
|
|
|
|
|
juceRect = component->getLocalArea (editor, juceRect);
|
|
|
|
|
|
|
|
rectToCheck->right = rectToCheck->left + roundToInt (juceRect.getWidth() * scale);
|
|
|
|
rectToCheck->bottom = rectToCheck->top + roundToInt (juceRect.getHeight() * scale);
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
rectToCheck->right = rectToCheck->left + roundToInt (juceRect.getWidth() * editorScaleFactor);
|
|
|
|
rectToCheck->bottom = rectToCheck->top + roundToInt (juceRect.getHeight() * editorScaleFactor);
|
|
|
|
#else
|
|
|
|
rectToCheck->right = rectToCheck->left + juceRect.getWidth();
|
|
|
|
rectToCheck->bottom = rectToCheck->top + juceRect.getHeight();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -978,20 +997,29 @@ private: |
|
|
|
tresult PLUGIN_API setContentScaleFactor (Steinberg::IPlugViewContentScaleSupport::ScaleFactor factor) override
|
|
|
|
{
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
scaleFactor = static_cast<float> (factor);
|
|
|
|
if (! approximatelyEqual ((float) factor, editorScaleFactor))
|
|
|
|
{
|
|
|
|
editorScaleFactor = (float) factor;
|
|
|
|
|
|
|
|
if (component == nullptr)
|
|
|
|
return kResultFalse;
|
|
|
|
if (auto* o = owner.get())
|
|
|
|
o->lastScaleFactorReceived = editorScaleFactor;
|
|
|
|
|
|
|
|
#if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
if (auto* ed = component->pluginEditor.get())
|
|
|
|
ed->setScaleFactor (scaleFactor);
|
|
|
|
#else
|
|
|
|
if (! approximatelyEqual (component->getNativeEditorScaleFactor(), scaleFactor))
|
|
|
|
component->nativeScaleFactorChanged ((double) scaleFactor);
|
|
|
|
#endif
|
|
|
|
if (component == nullptr)
|
|
|
|
return kResultFalse;
|
|
|
|
|
|
|
|
component->resizeHostWindow();
|
|
|
|
#if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
if (auto* ed = component->pluginEditor.get())
|
|
|
|
ed->setScaleFactor ((float) factor);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
component->resizeHostWindow();
|
|
|
|
|
|
|
|
if (getHostType().isBitwigStudio())
|
|
|
|
{
|
|
|
|
component->setTopLeftPosition (0, 0);
|
|
|
|
component->repaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return kResultTrue;
|
|
|
|
#else
|
|
|
|
@@ -1012,18 +1040,10 @@ private: |
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
struct ContentWrapperComponent : public Component
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
, public ComponentPeer::ScaleFactorListener,
|
|
|
|
public ComponentMovementWatcher
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
ContentWrapperComponent (JuceVST3Editor& editor, AudioProcessor& plugin)
|
|
|
|
:
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
ComponentMovementWatcher (this),
|
|
|
|
#endif
|
|
|
|
pluginEditor (plugin.createEditorIfNeeded()),
|
|
|
|
owner (editor)
|
|
|
|
: pluginEditor (plugin.createEditorIfNeeded()),
|
|
|
|
owner (editor)
|
|
|
|
{
|
|
|
|
setOpaque (true);
|
|
|
|
setBroughtToFrontOnMouseClick (true);
|
|
|
|
@@ -1054,12 +1074,6 @@ private: |
|
|
|
PopupMenu::dismissAllActiveMenus();
|
|
|
|
pluginEditor->processor.editorBeingDeleted (pluginEditor.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
for (int i = 0; i < ComponentPeer::getNumPeers(); ++i)
|
|
|
|
if (auto* p = ComponentPeer::getPeer (i))
|
|
|
|
p->removeScaleFactorListener (this);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void paint (Graphics& g) override
|
|
|
|
@@ -1091,10 +1105,27 @@ private: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
void checkScaleFactorIsCorrect()
|
|
|
|
{
|
|
|
|
if (auto* peer = pluginEditor->getPeer())
|
|
|
|
{
|
|
|
|
auto peerScaleFactor = (float) peer->getPlatformScaleFactor();
|
|
|
|
|
|
|
|
if (! approximatelyEqual (peerScaleFactor, owner.editorScaleFactor))
|
|
|
|
owner.setContentScaleFactor (peerScaleFactor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void resized() override
|
|
|
|
{
|
|
|
|
if (pluginEditor != nullptr)
|
|
|
|
{
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
checkScaleFactorIsCorrect();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (! isResizingParentToFitChild)
|
|
|
|
{
|
|
|
|
lastBounds = getLocalBounds();
|
|
|
|
@@ -1140,10 +1171,17 @@ private: |
|
|
|
|
|
|
|
if (owner.plugFrame != nullptr)
|
|
|
|
{
|
|
|
|
ViewRect newSize (0, 0, roundToInt (w * nativeScaleFactor), roundToInt (h * nativeScaleFactor));
|
|
|
|
isResizingParentToFitChild = true;
|
|
|
|
owner.plugFrame->resizeView (&owner, &newSize);
|
|
|
|
isResizingParentToFitChild = false;
|
|
|
|
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE
|
|
|
|
w = roundToInt (w * owner.editorScaleFactor);
|
|
|
|
h = roundToInt (h * owner.editorScaleFactor);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ViewRect newSize (0, 0, w, h);
|
|
|
|
|
|
|
|
{
|
|
|
|
const ScopedValueSetter<bool> resizingParentSetter (isResizingParentToFitChild, true);
|
|
|
|
owner.plugFrame->resizeView (&owner, &newSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if JUCE_MAC
|
|
|
|
if (host.isWavelab() || host.isReaper())
|
|
|
|
@@ -1155,49 +1193,6 @@ private: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float getNativeEditorScaleFactor() const noexcept { return nativeScaleFactor; }
|
|
|
|
|
|
|
|
#if ! JUCE_MAC
|
|
|
|
void componentMovedOrResized (bool, bool) override {}
|
|
|
|
|
|
|
|
void componentPeerChanged() override
|
|
|
|
{
|
|
|
|
if (auto* peer = getTopLevelComponent()->getPeer())
|
|
|
|
peer->addScaleFactorListener (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void componentVisibilityChanged() override
|
|
|
|
{
|
|
|
|
if (auto* peer = getTopLevelComponent()->getPeer())
|
|
|
|
nativeScaleFactor = (float) peer->getPlatformScaleFactor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void nativeScaleFactorChanged (double newScaleFactor) override
|
|
|
|
{
|
|
|
|
nativeScaleFactor = (float) newScaleFactor;
|
|
|
|
|
|
|
|
auto host = getHostType();
|
|
|
|
|
|
|
|
if (host.isWavelab())
|
|
|
|
{
|
|
|
|
Timer::callAfterDelay (250, [this] {
|
|
|
|
if (auto* peer = getPeer())
|
|
|
|
{
|
|
|
|
peer->updateBounds();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
resizeHostWindow();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else if (host.isBitwigStudio())
|
|
|
|
{
|
|
|
|
resizeHostWindow();
|
|
|
|
setTopLeftPosition (0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
std::unique_ptr<AudioProcessorEditor> pluginEditor;
|
|
|
|
|
|
|
|
private:
|
|
|
|
@@ -1207,8 +1202,6 @@ private: |
|
|
|
bool isResizingChildToFitParent = false;
|
|
|
|
bool isResizingParentToFitChild = false;
|
|
|
|
|
|
|
|
float nativeScaleFactor = 1.0f;
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent)
|
|
|
|
};
|
|
|
|
|
|
|
|
@@ -1222,10 +1215,10 @@ private: |
|
|
|
#if JUCE_MAC
|
|
|
|
void* macHostWindow = nullptr;
|
|
|
|
bool isNSView = false;
|
|
|
|
#else
|
|
|
|
float scaleFactor = 1.0f;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
float editorScaleFactor = 1.0f;
|
|
|
|
|
|
|
|
#if JUCE_WINDOWS
|
|
|
|
WindowsHooks hooks;
|
|
|
|
#endif
|
|
|
|
|