Browse Source

StandaloneFilterWindow: Respect editor's size constraints when adjusting size of component peer

v6.1.6
reuk 3 years ago
parent
commit
c0b78adcda
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
1 changed files with 108 additions and 26 deletions
  1. +108
    -26
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h

+ 108
- 26
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -709,6 +709,8 @@ public:
: DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton), : DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton),
optionsButton ("Options") optionsButton ("Options")
{ {
setConstrainer (&decoratorConstrainer);
#if JUCE_IOS || JUCE_ANDROID #if JUCE_IOS || JUCE_ANDROID
setTitleBarHeight (0); setTitleBarHeight (0);
#else #else
@@ -725,9 +727,9 @@ public:
#if JUCE_IOS || JUCE_ANDROID #if JUCE_IOS || JUCE_ANDROID
setFullScreen (true); setFullScreen (true);
setContentOwned (new MainContentComponent (*this), false);
updateContent();
#else #else
setContentOwned (new MainContentComponent (*this), true);
updateContent();
const auto windowScreenBounds = [this]() -> Rectangle<int> const auto windowScreenBounds = [this]() -> Rectangle<int>
{ {
@@ -798,7 +800,7 @@ public:
props->removeValue ("filterState"); props->removeValue ("filterState");
pluginHolder->createPlugin(); pluginHolder->createPlugin();
setContentOwned (new MainContentComponent (*this), true);
updateContent();
pluginHolder->startPlaying(); pluginHolder->startPlaying();
} }
@@ -839,6 +841,20 @@ public:
std::unique_ptr<StandalonePluginHolder> pluginHolder; std::unique_ptr<StandalonePluginHolder> pluginHolder;
private: private:
void updateContent()
{
auto* content = new MainContentComponent (*this);
decoratorConstrainer.setMainContentComponent (content);
#if JUCE_IOS || JUCE_ANDROID
constexpr auto resizeAutomatically = false;
#else
constexpr auto resizeAutomatically = true;
#endif
setContentOwned (content, resizeAutomatically);
}
void buttonClicked (Button*) override void buttonClicked (Button*) override
{ {
PopupMenu m; PopupMenu m;
@@ -914,6 +930,23 @@ private:
} }
} }
ComponentBoundsConstrainer* getEditorConstrainer() const
{
if (auto* e = editor.get())
return e->getConstrainer();
return nullptr;
}
BorderSize<int> computeBorder() const
{
const auto outer = owner.getContentComponentBorder();
return { outer.getTop() + (shouldShowNotification ? NotificationArea::height : 0),
outer.getLeft(),
outer.getBottom(),
outer.getRight() };
}
private: private:
//============================================================================== //==============================================================================
class NotificationArea : public Component class NotificationArea : public Component
@@ -975,29 +1008,6 @@ private:
{ {
const int extraHeight = shouldShowNotification ? NotificationArea::height : 0; const int extraHeight = shouldShowNotification ? NotificationArea::height : 0;
const auto rect = getSizeToContainEditor(); const auto rect = getSizeToContainEditor();
if (auto* editorConstrainer = editor->getConstrainer())
{
const auto borders = owner.getContentComponentBorder();
const auto windowBorders = [&]() -> BorderSize<int>
{
if (auto* peer = owner.getPeer())
if (const auto frameSize = peer->getFrameSizeIfPresent())
return *frameSize;
return {};
}();
const auto extraWindowWidth = borders.getLeftAndRight() + windowBorders.getLeftAndRight();
const auto extraWindowHeight = extraHeight + borders.getTopAndBottom() + windowBorders.getTopAndBottom();
owner.setResizeLimits (jmax (10, editorConstrainer->getMinimumWidth() + extraWindowWidth),
jmax (10, editorConstrainer->getMinimumHeight() + extraWindowHeight),
editorConstrainer->getMaximumWidth() + extraWindowWidth,
editorConstrainer->getMaximumHeight() + extraWindowHeight);
}
setSize (rect.getWidth(), rect.getHeight() + extraHeight); setSize (rect.getWidth(), rect.getHeight() + extraHeight);
} }
#endif #endif
@@ -1046,8 +1056,80 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
}; };
/* This custom constrainer checks with the AudioProcessorEditor (which might itself be
constrained) to ensure that any size we choose for the standalone window will be suitable
for the editor too.
Without this constrainer, attempting to resize the standalone window may set bounds on the
peer that are unsupported by the inner editor. In this scenario, the peer will be set to a
'bad' size, then the inner editor will be resized. The editor will check the new bounds with
its own constrainer, and may set itself to a more suitable size. After that, the resizable
window will see that its content component has changed size, and set the bounds of the peer
accordingly. The end result is that the peer is resized twice in a row to different sizes,
which can appear glitchy/flickery to the user.
*/
struct DecoratorConstrainer : public ComponentBoundsConstrainer
{
void checkBounds (Rectangle<int>& bounds,
const Rectangle<int>& previousBounds,
const Rectangle<int>& limits,
bool isStretchingTop,
bool isStretchingLeft,
bool isStretchingBottom,
bool isStretchingRight) override
{
auto* decorated = contentComponent != nullptr ? contentComponent->getEditorConstrainer()
: nullptr;
if (decorated != nullptr)
{
const auto border = contentComponent->computeBorder();
const auto requestedBounds = bounds;
border.subtractFrom (bounds);
decorated->checkBounds (bounds,
border.subtractedFrom (previousBounds),
limits,
isStretchingTop,
isStretchingLeft,
isStretchingBottom,
isStretchingRight);
border.addTo (bounds);
bounds = bounds.withPosition (requestedBounds.getPosition());
if (isStretchingTop && ! isStretchingBottom)
bounds = bounds.withBottomY (previousBounds.getBottom());
if (! isStretchingTop && isStretchingBottom)
bounds = bounds.withY (previousBounds.getY());
if (isStretchingLeft && ! isStretchingRight)
bounds = bounds.withRightX (previousBounds.getRight());
if (! isStretchingLeft && isStretchingRight)
bounds = bounds.withX (previousBounds.getX());
}
else
{
ComponentBoundsConstrainer::checkBounds (bounds,
previousBounds,
limits,
isStretchingTop,
isStretchingLeft,
isStretchingBottom,
isStretchingRight);
}
}
void setMainContentComponent (MainContentComponent* in) { contentComponent = in; }
private:
MainContentComponent* contentComponent = nullptr;
};
//============================================================================== //==============================================================================
TextButton optionsButton; TextButton optionsButton;
DecoratorConstrainer decoratorConstrainer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandaloneFilterWindow) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandaloneFilterWindow)
}; };


Loading…
Cancel
Save