|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2015 - ROLI Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- ComponentBoundsConstrainer::ComponentBoundsConstrainer() noexcept
- : minW (0), maxW (0x3fffffff),
- minH (0), maxH (0x3fffffff),
- minOffTop (0),
- minOffLeft (0),
- minOffBottom (0),
- minOffRight (0),
- aspectRatio (0.0)
- {
- }
-
- ComponentBoundsConstrainer::~ComponentBoundsConstrainer()
- {
- }
-
- //==============================================================================
- void ComponentBoundsConstrainer::setMinimumWidth (const int minimumWidth) noexcept { minW = minimumWidth; }
- void ComponentBoundsConstrainer::setMaximumWidth (const int maximumWidth) noexcept { maxW = maximumWidth; }
- void ComponentBoundsConstrainer::setMinimumHeight (const int minimumHeight) noexcept { minH = minimumHeight; }
- void ComponentBoundsConstrainer::setMaximumHeight (const int maximumHeight) noexcept { maxH = maximumHeight; }
-
- void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const int minimumHeight) noexcept
- {
- jassert (maxW >= minimumWidth);
- jassert (maxH >= minimumHeight);
- jassert (minimumWidth > 0 && minimumHeight > 0);
-
- minW = minimumWidth;
- minH = minimumHeight;
-
- if (minW > maxW) maxW = minW;
- if (minH > maxH) maxH = minH;
- }
-
- void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const int maximumHeight) noexcept
- {
- jassert (maximumWidth >= minW);
- jassert (maximumHeight >= minH);
- jassert (maximumWidth > 0 && maximumHeight > 0);
-
- maxW = jmax (minW, maximumWidth);
- maxH = jmax (minH, maximumHeight);
- }
-
- void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth,
- const int minimumHeight,
- const int maximumWidth,
- const int maximumHeight) noexcept
- {
- jassert (maximumWidth >= minimumWidth);
- jassert (maximumHeight >= minimumHeight);
- jassert (maximumWidth > 0 && maximumHeight > 0);
- jassert (minimumWidth > 0 && minimumHeight > 0);
-
- minW = jmax (0, minimumWidth);
- minH = jmax (0, minimumHeight);
- maxW = jmax (minW, maximumWidth);
- maxH = jmax (minH, maximumHeight);
- }
-
- void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhenOffTheTop,
- const int minimumWhenOffTheLeft,
- const int minimumWhenOffTheBottom,
- const int minimumWhenOffTheRight) noexcept
- {
- minOffTop = minimumWhenOffTheTop;
- minOffLeft = minimumWhenOffTheLeft;
- minOffBottom = minimumWhenOffTheBottom;
- minOffRight = minimumWhenOffTheRight;
- }
-
- void ComponentBoundsConstrainer::setFixedAspectRatio (const double widthOverHeight) noexcept
- {
- aspectRatio = jmax (0.0, widthOverHeight);
- }
-
- double ComponentBoundsConstrainer::getFixedAspectRatio() const noexcept
- {
- return aspectRatio;
- }
-
- void ComponentBoundsConstrainer::setBoundsForComponent (Component* const component,
- const Rectangle<int>& targetBounds,
- const bool isStretchingTop,
- const bool isStretchingLeft,
- const bool isStretchingBottom,
- const bool isStretchingRight)
- {
- jassert (component != nullptr);
-
- Rectangle<int> limits, bounds (targetBounds);
- BorderSize<int> border;
-
- if (Component* const parent = component->getParentComponent())
- {
- limits.setSize (parent->getWidth(), parent->getHeight());
- }
- else
- {
- if (ComponentPeer* const peer = component->getPeer())
- border = peer->getFrameSize();
-
- limits = Desktop::getInstance().getDisplays().getDisplayContaining (bounds.getCentre()).userArea;
- }
-
- border.addTo (bounds);
-
- checkBounds (bounds,
- border.addedTo (component->getBounds()), limits,
- isStretchingTop, isStretchingLeft,
- isStretchingBottom, isStretchingRight);
-
- border.subtractFrom (bounds);
-
- applyBoundsToComponent (component, bounds);
- }
-
- void ComponentBoundsConstrainer::checkComponentBounds (Component* component)
- {
- setBoundsForComponent (component, component->getBounds(),
- false, false, false, false);
- }
-
- void ComponentBoundsConstrainer::applyBoundsToComponent (Component* component,
- const Rectangle<int>& bounds)
- {
- if (Component::Positioner* const positioner = component->getPositioner())
- positioner->applyNewBounds (bounds);
- else
- component->setBounds (bounds);
- }
-
- //==============================================================================
- void ComponentBoundsConstrainer::resizeStart()
- {
- }
-
- void ComponentBoundsConstrainer::resizeEnd()
- {
- }
-
- //==============================================================================
- void ComponentBoundsConstrainer::checkBounds (Rectangle<int>& bounds,
- const Rectangle<int>& old,
- const Rectangle<int>& limits,
- const bool isStretchingTop,
- const bool isStretchingLeft,
- const bool isStretchingBottom,
- const bool isStretchingRight)
- {
- if (isStretchingLeft)
- bounds.setLeft (jlimit (old.getRight() - maxW, old.getRight() - minW, bounds.getX()));
- else
- bounds.setWidth (jlimit (minW, maxW, bounds.getWidth()));
-
- if (isStretchingTop)
- bounds.setTop (jlimit (old.getBottom() - maxH, old.getBottom() - minH, bounds.getY()));
- else
- bounds.setHeight (jlimit (minH, maxH, bounds.getHeight()));
-
- if (bounds.isEmpty())
- return;
-
- if (minOffTop > 0)
- {
- const int limit = limits.getY() + jmin (minOffTop - bounds.getHeight(), 0);
-
- if (bounds.getY() < limit)
- {
- if (isStretchingTop)
- bounds.setTop (limits.getY());
- else
- bounds.setY (limit);
- }
- }
-
- if (minOffLeft > 0)
- {
- const int limit = limits.getX() + jmin (minOffLeft - bounds.getWidth(), 0);
-
- if (bounds.getX() < limit)
- {
- if (isStretchingLeft)
- bounds.setLeft (limits.getX());
- else
- bounds.setX (limit);
- }
- }
-
- if (minOffBottom > 0)
- {
- const int limit = limits.getBottom() - jmin (minOffBottom, bounds.getHeight());
-
- if (bounds.getY() > limit)
- {
- if (isStretchingBottom)
- bounds.setBottom (limits.getBottom());
- else
- bounds.setY (limit);
- }
- }
-
- if (minOffRight > 0)
- {
- const int limit = limits.getRight() - jmin (minOffRight, bounds.getWidth());
-
- if (bounds.getX() > limit)
- {
- if (isStretchingRight)
- bounds.setRight (limits.getRight());
- else
- bounds.setX (limit);
- }
- }
-
- // constrain the aspect ratio if one has been specified..
- if (aspectRatio > 0.0)
- {
- bool adjustWidth;
-
- if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
- {
- adjustWidth = true;
- }
- else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
- {
- adjustWidth = false;
- }
- else
- {
- const double oldRatio = (old.getHeight() > 0) ? std::abs (old.getWidth() / (double) old.getHeight()) : 0.0;
- const double newRatio = std::abs (bounds.getWidth() / (double) bounds.getHeight());
-
- adjustWidth = (oldRatio > newRatio);
- }
-
- if (adjustWidth)
- {
- bounds.setWidth (roundToInt (bounds.getHeight() * aspectRatio));
-
- if (bounds.getWidth() > maxW || bounds.getWidth() < minW)
- {
- bounds.setWidth (jlimit (minW, maxW, bounds.getWidth()));
- bounds.setHeight (roundToInt (bounds.getWidth() / aspectRatio));
- }
- }
- else
- {
- bounds.setHeight (roundToInt (bounds.getWidth() / aspectRatio));
-
- if (bounds.getHeight() > maxH || bounds.getHeight() < minH)
- {
- bounds.setHeight (jlimit (minH, maxH, bounds.getHeight()));
- bounds.setWidth (roundToInt (bounds.getHeight() * aspectRatio));
- }
- }
-
- if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
- {
- bounds.setX (old.getX() + (old.getWidth() - bounds.getWidth()) / 2);
- }
- else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
- {
- bounds.setY (old.getY() + (old.getHeight() - bounds.getHeight()) / 2);
- }
- else
- {
- if (isStretchingLeft)
- bounds.setX (old.getRight() - bounds.getWidth());
-
- if (isStretchingTop)
- bounds.setY (old.getBottom() - bounds.getHeight());
- }
- }
-
- jassert (! bounds.isEmpty());
- }
|