diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h index 4a60e94f44..e74caf185e 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h @@ -1089,57 +1089,17 @@ private: 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 + class DecoratorConstrainer : public BorderedComponentBoundsConstrainer { - void checkBounds (Rectangle& bounds, - const Rectangle& previousBounds, - const Rectangle& limits, - bool isStretchingTop, - bool isStretchingLeft, - bool isStretchingBottom, - bool isStretchingRight) override + public: + ComponentBoundsConstrainer* getWrappedConstrainer() const override { - auto* decorated = contentComponent != nullptr ? contentComponent->getEditorConstrainer() - : nullptr; + return 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); - } + BorderSize getAdditionalBorder() const override + { + return contentComponent != nullptr ? contentComponent->computeBorder() : BorderSize{}; } void setMainContentComponent (MainContentComponent* in) { contentComponent = in; } diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 05a13aa636..4762872902 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -268,6 +268,7 @@ #include "keyboard/juce_ModifierKeys.cpp" #include "layout/juce_ComponentAnimator.cpp" #include "layout/juce_ComponentBoundsConstrainer.cpp" +#include "layout/juce_BorderedComponentBoundsConstrainer.cpp" #include "layout/juce_ComponentBuilder.cpp" #include "layout/juce_ComponentMovementWatcher.cpp" #include "layout/juce_ConcertinaPanel.cpp" diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index f421760781..a5e7cbe8e7 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -199,6 +199,7 @@ namespace juce #include "desktop/juce_Desktop.h" #include "desktop/juce_Displays.h" #include "layout/juce_ComponentBoundsConstrainer.h" +#include "layout/juce_BorderedComponentBoundsConstrainer.h" #include "mouse/juce_ComponentDragger.h" #include "mouse/juce_DragAndDropTarget.h" #include "mouse/juce_DragAndDropContainer.h" diff --git a/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.cpp b/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.cpp new file mode 100644 index 0000000000..7e1268a078 --- /dev/null +++ b/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.cpp @@ -0,0 +1,77 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 7 End-User License + Agreement and JUCE Privacy Policy. + + End User License Agreement: www.juce.com/juce-7-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +void BorderedComponentBoundsConstrainer::checkBounds (Rectangle& bounds, + const Rectangle& previousBounds, + const Rectangle& limits, + bool isStretchingTop, + bool isStretchingLeft, + bool isStretchingBottom, + bool isStretchingRight) +{ + if (auto* decorated = getWrappedConstrainer()) + { + const auto border = getAdditionalBorder(); + 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); + } +} + +} // namespace juce diff --git a/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.h b/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.h new file mode 100644 index 0000000000..c759e6e7a2 --- /dev/null +++ b/modules/juce_gui_basics/layout/juce_BorderedComponentBoundsConstrainer.h @@ -0,0 +1,69 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 7 End-User License + Agreement and JUCE Privacy Policy. + + End User License Agreement: www.juce.com/juce-7-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +/** + A ComponentBoundsConstrainer that can be used to add a constant border onto another + ComponentBoundsConstrainer. + + This is useful when trying to constrain the size of a resizable window or + other component that wraps a constrained component, such as a plugin + editor. + + @see ResizableCornerComponent, ResizableBorderComponent, ResizableWindow, + ComponentBoundsConstrainer + + @tags{GUI} +*/ +class JUCE_API BorderedComponentBoundsConstrainer : public ComponentBoundsConstrainer +{ +public: + /** Default constructor. */ + BorderedComponentBoundsConstrainer() = default; + + /** Returns a pointer to another constrainer that will be used as the + base for any resizing operations. + */ + virtual ComponentBoundsConstrainer* getWrappedConstrainer() const = 0; + + /** Returns the border that should be applied to the constrained bounds. */ + virtual BorderSize getAdditionalBorder() const = 0; + + /** @internal */ + void checkBounds (Rectangle& bounds, + const Rectangle& previousBounds, + const Rectangle& limits, + bool isStretchingTop, + bool isStretchingLeft, + bool isStretchingBottom, + bool isStretchingRight) override; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BorderedComponentBoundsConstrainer) +}; + +} // namespace juce