LMMS
Loading...
Searching...
No Matches
juce_ComponentBoundsConstrainer.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
31
32//==============================================================================
33void ComponentBoundsConstrainer::setMinimumWidth (int minimumWidth) noexcept { minW = minimumWidth; }
34void ComponentBoundsConstrainer::setMaximumWidth (int maximumWidth) noexcept { maxW = maximumWidth; }
35void ComponentBoundsConstrainer::setMinimumHeight (int minimumHeight) noexcept { minH = minimumHeight; }
36void ComponentBoundsConstrainer::setMaximumHeight (int maximumHeight) noexcept { maxH = maximumHeight; }
37
38void ComponentBoundsConstrainer::setMinimumSize (int minimumWidth, int minimumHeight) noexcept
39{
40 jassert (maxW >= minimumWidth);
41 jassert (maxH >= minimumHeight);
42 jassert (minimumWidth > 0 && minimumHeight > 0);
43
44 minW = minimumWidth;
45 minH = minimumHeight;
46
47 if (minW > maxW) maxW = minW;
48 if (minH > maxH) maxH = minH;
49}
50
51void ComponentBoundsConstrainer::setMaximumSize (int maximumWidth, int maximumHeight) noexcept
52{
53 jassert (maximumWidth >= minW);
54 jassert (maximumHeight >= minH);
55 jassert (maximumWidth > 0 && maximumHeight > 0);
56
57 maxW = jmax (minW, maximumWidth);
58 maxH = jmax (minH, maximumHeight);
59}
60
62 int minimumHeight,
63 int maximumWidth,
64 int maximumHeight) noexcept
65{
66 jassert (maximumWidth >= minimumWidth);
67 jassert (maximumHeight >= minimumHeight);
68 jassert (maximumWidth > 0 && maximumHeight > 0);
69 jassert (minimumWidth > 0 && minimumHeight > 0);
70
71 minW = jmax (0, minimumWidth);
72 minH = jmax (0, minimumHeight);
73 maxW = jmax (minW, maximumWidth);
74 maxH = jmax (minH, maximumHeight);
75}
76
78 int minimumWhenOffTheLeft,
79 int minimumWhenOffTheBottom,
80 int minimumWhenOffTheRight) noexcept
81{
82 minOffTop = minimumWhenOffTheTop;
83 minOffLeft = minimumWhenOffTheLeft;
84 minOffBottom = minimumWhenOffTheBottom;
85 minOffRight = minimumWhenOffTheRight;
86}
87
88void ComponentBoundsConstrainer::setFixedAspectRatio (double widthOverHeight) noexcept
89{
90 aspectRatio = jmax (0.0, widthOverHeight);
91}
92
97
99 Rectangle<int> targetBounds,
100 bool isStretchingTop,
101 bool isStretchingLeft,
102 bool isStretchingBottom,
103 bool isStretchingRight)
104{
105 jassert (component != nullptr);
106
107 auto bounds = targetBounds;
108
109 auto limits = [&]() -> Rectangle<int>
110 {
111 if (auto* parent = component->getParentComponent())
112 return { parent->getWidth(), parent->getHeight() };
113
114 const auto globalBounds = component->localAreaToGlobal (targetBounds - component->getPosition());
115
116 if (auto* display = Desktop::getInstance().getDisplays().getDisplayForPoint (globalBounds.getCentre()))
117 return component->getLocalArea (nullptr, display->userArea) + component->getPosition();
118
119 const auto max = std::numeric_limits<int>::max();
120 return { max, max };
121 }();
122
123 auto border = [&]() -> BorderSize<int>
124 {
125 if (component->getParentComponent() == nullptr)
126 if (auto* peer = component->getPeer())
127 if (const auto frameSize = peer->getFrameSizeIfPresent())
128 return *frameSize;
129
130 return {};
131 }();
132
133 border.addTo (bounds);
134
135 checkBounds (bounds,
136 border.addedTo (component->getBounds()), limits,
137 isStretchingTop, isStretchingLeft,
138 isStretchingBottom, isStretchingRight);
139
140 border.subtractFrom (bounds);
141
142 applyBoundsToComponent (*component, bounds);
143}
144
146{
147 setBoundsForComponent (component, component->getBounds(),
148 false, false, false, false);
149}
150
152{
153 if (auto* positioner = component.getPositioner())
154 positioner->applyNewBounds (bounds);
155 else
156 component.setBounds (bounds);
157}
158
159//==============================================================================
163
167
168//==============================================================================
170 const Rectangle<int>& old,
171 const Rectangle<int>& limits,
172 bool isStretchingTop,
173 bool isStretchingLeft,
174 bool isStretchingBottom,
175 bool isStretchingRight)
176{
177 if (isStretchingLeft)
178 bounds.setLeft (jlimit (old.getRight() - maxW, old.getRight() - minW, bounds.getX()));
179 else
180 bounds.setWidth (jlimit (minW, maxW, bounds.getWidth()));
181
182 if (isStretchingTop)
183 bounds.setTop (jlimit (old.getBottom() - maxH, old.getBottom() - minH, bounds.getY()));
184 else
185 bounds.setHeight (jlimit (minH, maxH, bounds.getHeight()));
186
187 if (bounds.isEmpty())
188 return;
189
190 if (minOffTop > 0)
191 {
192 const int limit = limits.getY() + jmin (minOffTop - bounds.getHeight(), 0);
193
194 if (bounds.getY() < limit)
195 {
196 if (isStretchingTop)
197 bounds.setTop (limits.getY());
198 else
199 bounds.setY (limit);
200 }
201 }
202
203 if (minOffLeft > 0)
204 {
205 const int limit = limits.getX() + jmin (minOffLeft - bounds.getWidth(), 0);
206
207 if (bounds.getX() < limit)
208 {
209 if (isStretchingLeft)
210 bounds.setLeft (limits.getX());
211 else
212 bounds.setX (limit);
213 }
214 }
215
216 if (minOffBottom > 0)
217 {
218 const int limit = limits.getBottom() - jmin (minOffBottom, bounds.getHeight());
219
220 if (bounds.getY() > limit)
221 {
222 if (isStretchingBottom)
223 bounds.setBottom (limits.getBottom());
224 else
225 bounds.setY (limit);
226 }
227 }
228
229 if (minOffRight > 0)
230 {
231 const int limit = limits.getRight() - jmin (minOffRight, bounds.getWidth());
232
233 if (bounds.getX() > limit)
234 {
235 if (isStretchingRight)
236 bounds.setRight (limits.getRight());
237 else
238 bounds.setX (limit);
239 }
240 }
241
242 // constrain the aspect ratio if one has been specified..
243 if (aspectRatio > 0.0)
244 {
245 bool adjustWidth;
246
247 if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
248 {
249 adjustWidth = true;
250 }
251 else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
252 {
253 adjustWidth = false;
254 }
255 else
256 {
257 const double oldRatio = (old.getHeight() > 0) ? std::abs (old.getWidth() / (double) old.getHeight()) : 0.0;
258 const double newRatio = std::abs (bounds.getWidth() / (double) bounds.getHeight());
259
260 adjustWidth = (oldRatio > newRatio);
261 }
262
263 if (adjustWidth)
264 {
265 bounds.setWidth (roundToInt (bounds.getHeight() * aspectRatio));
266
267 if (bounds.getWidth() > maxW || bounds.getWidth() < minW)
268 {
269 bounds.setWidth (jlimit (minW, maxW, bounds.getWidth()));
270 bounds.setHeight (roundToInt (bounds.getWidth() / aspectRatio));
271 }
272 }
273 else
274 {
275 bounds.setHeight (roundToInt (bounds.getWidth() / aspectRatio));
276
277 if (bounds.getHeight() > maxH || bounds.getHeight() < minH)
278 {
279 bounds.setHeight (jlimit (minH, maxH, bounds.getHeight()));
280 bounds.setWidth (roundToInt (bounds.getHeight() * aspectRatio));
281 }
282 }
283
284 if ((isStretchingTop || isStretchingBottom) && ! (isStretchingLeft || isStretchingRight))
285 {
286 bounds.setX (old.getX() + (old.getWidth() - bounds.getWidth()) / 2);
287 }
288 else if ((isStretchingLeft || isStretchingRight) && ! (isStretchingTop || isStretchingBottom))
289 {
290 bounds.setY (old.getY() + (old.getHeight() - bounds.getHeight()) / 2);
291 }
292 else
293 {
294 if (isStretchingLeft)
295 bounds.setX (old.getRight() - bounds.getWidth());
296
297 if (isStretchingTop)
298 bounds.setY (old.getBottom() - bounds.getHeight());
299 }
300 }
301
302 jassert (! bounds.isEmpty());
303}
304
305} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
T limit(T val, T min, T max)
Definition Util.h:78
Definition juce_BorderSize.h:42
double getFixedAspectRatio() const noexcept
Definition juce_ComponentBoundsConstrainer.cpp:93
void setMaximumHeight(int maximumHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:36
double aspectRatio
Definition juce_ComponentBoundsConstrainer.h:192
void setMinimumSize(int minimumWidth, int minimumHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:38
void setFixedAspectRatio(double widthOverHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:88
int maxH
Definition juce_ComponentBoundsConstrainer.h:190
int minOffTop
Definition juce_ComponentBoundsConstrainer.h:191
void setMinimumOnscreenAmounts(int minimumWhenOffTheTop, int minimumWhenOffTheLeft, int minimumWhenOffTheBottom, int minimumWhenOffTheRight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:77
void setBoundsForComponent(Component *component, Rectangle< int > bounds, bool isStretchingTop, bool isStretchingLeft, bool isStretchingBottom, bool isStretchingRight)
Definition juce_ComponentBoundsConstrainer.cpp:98
void setMinimumWidth(int minimumWidth) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:33
int minW
Definition juce_ComponentBoundsConstrainer.h:190
void setMaximumSize(int maximumWidth, int maximumHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:51
void setMinimumHeight(int minimumHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:35
virtual void resizeEnd()
Definition juce_ComponentBoundsConstrainer.cpp:164
virtual void applyBoundsToComponent(Component &, Rectangle< int > bounds)
Definition juce_ComponentBoundsConstrainer.cpp:151
int maxW
Definition juce_ComponentBoundsConstrainer.h:190
void setMaximumWidth(int maximumWidth) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:34
virtual ~ComponentBoundsConstrainer()
Definition juce_ComponentBoundsConstrainer.cpp:30
int minOffBottom
Definition juce_ComponentBoundsConstrainer.h:191
int minOffRight
Definition juce_ComponentBoundsConstrainer.h:191
ComponentBoundsConstrainer() noexcept
Definition juce_ComponentBoundsConstrainer.cpp:29
void setSizeLimits(int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight) noexcept
Definition juce_ComponentBoundsConstrainer.cpp:61
int minOffLeft
Definition juce_ComponentBoundsConstrainer.h:191
virtual void resizeStart()
Definition juce_ComponentBoundsConstrainer.cpp:160
void checkComponentBounds(Component *component)
Definition juce_ComponentBoundsConstrainer.cpp:145
int minH
Definition juce_ComponentBoundsConstrainer.h:190
virtual void checkBounds(Rectangle< int > &bounds, const Rectangle< int > &previousBounds, const Rectangle< int > &limits, bool isStretchingTop, bool isStretchingLeft, bool isStretchingBottom, bool isStretchingRight)
Definition juce_ComponentBoundsConstrainer.cpp:169
Definition juce_Component.h:36
Component * getParentComponent() const noexcept
Definition juce_Component.h:804
Point< int > getPosition() const noexcept
Definition juce_Component.h:286
Rectangle< int > getLocalArea(const Component *sourceComponent, Rectangle< int > areaRelativeToSourceComponent) const
Definition juce_Component.cpp:1138
Positioner * getPositioner() const noexcept
Definition juce_Component.cpp:2270
Rectangle< int > getBounds() const noexcept
Definition juce_Component.h:304
Rectangle< int > localAreaToGlobal(Rectangle< int > localArea) const
Definition juce_Component.cpp:1143
void setBounds(int x, int y, int width, int height)
Definition juce_Component.cpp:1147
ComponentPeer * getPeer() const
Definition juce_Component.cpp:801
static Desktop &JUCE_CALLTYPE getInstance()
Definition juce_Desktop.cpp:50
Definition juce_Rectangle.h:67
ValueType getRight() const noexcept
Definition juce_Rectangle.h:139
void setLeft(ValueType newLeft) noexcept
Definition juce_Rectangle.h:261
void setHeight(ValueType newHeight) noexcept
Definition juce_Rectangle.h:204
ValueType getHeight() const noexcept
Definition juce_Rectangle.h:136
void setRight(ValueType newRight) noexcept
Definition juce_Rectangle.h:285
void setBottom(ValueType newBottom) noexcept
Definition juce_Rectangle.h:297
void setWidth(ValueType newWidth) noexcept
Definition juce_Rectangle.h:201
ValueType getBottom() const noexcept
Definition juce_Rectangle.h:142
void setTop(ValueType newTop) noexcept
Definition juce_Rectangle.h:273
ValueType getX() const noexcept
Definition juce_Rectangle.h:127
ValueType getWidth() const noexcept
Definition juce_Rectangle.h:133
void setX(ValueType newX) noexcept
Definition juce_Rectangle.h:195
void setY(ValueType newY) noexcept
Definition juce_Rectangle.h:198
bool isEmpty() const noexcept
Definition juce_Rectangle.h:121
ValueType getY() const noexcept
Definition juce_Rectangle.h:130
static ZCONST unsigned border[]
Definition inflate.c:749
static uintptr_t parent
Definition pugl.h:1644
#define jassert(expression)
Definition carla_juce.cpp:31
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
#define max(x, y)
Definition os.h:78
#define const
Definition zconf.h:137