JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_StretchableLayoutManager.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//==============================================================================
34{
35 items.clear();
36 totalSize = 0;
37}
38
40 const double minimumSize,
41 const double maximumSize,
42 const double preferredSize)
43{
44 auto* layout = getInfoFor (itemIndex);
45
46 if (layout == nullptr)
47 {
48 layout = new ItemLayoutProperties();
49 layout->itemIndex = itemIndex;
50
51 int i;
52 for (i = 0; i < items.size(); ++i)
53 if (items.getUnchecked (i)->itemIndex > itemIndex)
54 break;
55
56 items.insert (i, layout);
57 }
58
59 layout->minSize = minimumSize;
60 layout->maxSize = maximumSize;
61 layout->preferredSize = preferredSize;
62 layout->currentSize = 0;
63}
64
66 double& minimumSize,
67 double& maximumSize,
68 double& preferredSize) const
69{
70 if (auto* layout = getInfoFor (itemIndex))
71 {
72 minimumSize = layout->minSize;
73 maximumSize = layout->maxSize;
74 preferredSize = layout->preferredSize;
75 return true;
76 }
77
78 return false;
79}
80
81//==============================================================================
82void StretchableLayoutManager::setTotalSize (const int newTotalSize)
83{
84 totalSize = newTotalSize;
85
86 fitComponentsIntoSpace (0, items.size(), totalSize, 0);
87}
88
90{
91 int pos = 0;
92
93 for (int i = 0; i < itemIndex; ++i)
94 if (auto* layout = getInfoFor (i))
95 pos += layout->currentSize;
96
97 return pos;
98}
99
101{
102 if (auto* layout = getInfoFor (itemIndex))
103 return layout->currentSize;
104
105 return 0;
106}
107
109{
110 if (auto* layout = getInfoFor (itemIndex))
111 return -layout->currentSize / (double) totalSize;
112
113 return 0;
114}
115
117 int newPosition)
118{
119 for (int i = items.size(); --i >= 0;)
120 {
121 auto* layout = items.getUnchecked (i);
122
123 if (layout->itemIndex == itemIndex)
124 {
125 auto realTotalSize = jmax (totalSize, getMinimumSizeOfItems (0, items.size()));
126 auto minSizeAfterThisComp = getMinimumSizeOfItems (i, items.size());
127 auto maxSizeAfterThisComp = getMaximumSizeOfItems (i + 1, items.size());
128
129 newPosition = jmax (newPosition, totalSize - maxSizeAfterThisComp - layout->currentSize);
131
132 auto endPos = fitComponentsIntoSpace (0, i, newPosition, 0);
133
134 endPos += layout->currentSize;
135
136 fitComponentsIntoSpace (i + 1, items.size(), totalSize - endPos, endPos);
137 updatePrefSizesToMatchCurrentPositions();
138 break;
139 }
140 }
141}
142
143//==============================================================================
145 int numComponents,
146 int x, int y, int w, int h,
147 const bool vertically,
148 const bool resizeOtherDimension)
149{
150 setTotalSize (vertically ? h : w);
151 int pos = vertically ? y : x;
152
153 for (int i = 0; i < numComponents; ++i)
154 {
155 if (auto* layout = getInfoFor (i))
156 {
157 if (auto* c = components[i])
158 {
159 if (i == numComponents - 1)
160 {
161 // if it's the last item, crop it to exactly fit the available space..
163 {
164 if (vertically)
165 c->setBounds (x, pos, w, jmax (layout->currentSize, h - pos));
166 else
167 c->setBounds (pos, y, jmax (layout->currentSize, w - pos), h);
168 }
169 else
170 {
171 if (vertically)
172 c->setBounds (c->getX(), pos, c->getWidth(), jmax (layout->currentSize, h - pos));
173 else
174 c->setBounds (pos, c->getY(), jmax (layout->currentSize, w - pos), c->getHeight());
175 }
176 }
177 else
178 {
180 {
181 if (vertically)
182 c->setBounds (x, pos, w, layout->currentSize);
183 else
184 c->setBounds (pos, y, layout->currentSize, h);
185 }
186 else
187 {
188 if (vertically)
189 c->setBounds (c->getX(), pos, c->getWidth(), layout->currentSize);
190 else
191 c->setBounds (pos, c->getY(), layout->currentSize, c->getHeight());
192 }
193 }
194 }
195
196 pos += layout->currentSize;
197 }
198 }
199}
200
201
202//==============================================================================
203StretchableLayoutManager::ItemLayoutProperties* StretchableLayoutManager::getInfoFor (const int itemIndex) const
204{
205 for (auto* i : items)
206 if (i->itemIndex == itemIndex)
207 return i;
208
209 return nullptr;
210}
211
212int StretchableLayoutManager::fitComponentsIntoSpace (const int startIndex,
213 const int endIndex,
214 const int availableSpace,
215 int startPos)
216{
217 // calculate the total sizes
218 double totalIdealSize = 0.0;
219 int totalMinimums = 0;
220
221 for (int i = startIndex; i < endIndex; ++i)
222 {
223 auto* layout = items.getUnchecked (i);
224
225 layout->currentSize = sizeToRealSize (layout->minSize, totalSize);
226
227 totalMinimums += layout->currentSize;
228 totalIdealSize += sizeToRealSize (layout->preferredSize, totalSize);
229 }
230
231 if (totalIdealSize <= 0)
232 totalIdealSize = 1.0;
233
234 // now calc the best sizes..
236
237 while (extraSpace > 0)
238 {
239 int numWantingMoreSpace = 0;
241
242 // first figure out how many comps want a slice of the extra space..
243 for (int i = startIndex; i < endIndex; ++i)
244 {
245 auto* layout = items.getUnchecked (i);
246
247 auto sizeWanted = sizeToRealSize (layout->preferredSize, totalSize);
248
249 auto bestSize = jlimit (layout->currentSize,
250 jmax (layout->currentSize,
251 sizeToRealSize (layout->maxSize, totalSize)),
253
254 if (bestSize > layout->currentSize)
256 }
257
258 // ..share out the extra space..
259 for (int i = startIndex; i < endIndex; ++i)
260 {
261 auto* layout = items.getUnchecked (i);
262
263 auto sizeWanted = sizeToRealSize (layout->preferredSize, totalSize);
264
265 auto bestSize = jlimit (layout->currentSize,
266 jmax (layout->currentSize, sizeToRealSize (layout->maxSize, totalSize)),
268
269 auto extraWanted = bestSize - layout->currentSize;
270
271 if (extraWanted > 0)
272 {
275
276 if (extraAllowed > 0)
277 {
280
281 layout->currentSize += extraAllowed;
283 }
284 }
285 }
286
288 break;
289 }
290
291 // ..and calculate the end position
292 for (int i = startIndex; i < endIndex; ++i)
293 {
294 auto* layout = items.getUnchecked (i);
295 startPos += layout->currentSize;
296 }
297
298 return startPos;
299}
300
301int StretchableLayoutManager::getMinimumSizeOfItems (const int startIndex,
302 const int endIndex) const
303{
304 int totalMinimums = 0;
305
306 for (int i = startIndex; i < endIndex; ++i)
307 totalMinimums += sizeToRealSize (items.getUnchecked (i)->minSize, totalSize);
308
309 return totalMinimums;
310}
311
312int StretchableLayoutManager::getMaximumSizeOfItems (const int startIndex, const int endIndex) const
313{
314 int totalMaximums = 0;
315
316 for (int i = startIndex; i < endIndex; ++i)
317 totalMaximums += sizeToRealSize (items.getUnchecked (i)->maxSize, totalSize);
318
319 return totalMaximums;
320}
321
322void StretchableLayoutManager::updatePrefSizesToMatchCurrentPositions()
323{
324 for (int i = 0; i < items.size(); ++i)
325 {
326 auto* layout = items.getUnchecked (i);
327
328 layout->preferredSize
329 = (layout->preferredSize < 0) ? getItemCurrentRelativeSize (i)
331 }
332}
333
334int StretchableLayoutManager::sizeToRealSize (double size, int totalSpace)
335{
336 if (size < 0)
337 size *= -totalSpace;
338
339 return roundToInt (jmax (1.0, size));
340}
341
342} // namespace juce
The base class for all JUCE user-interface objects.
int size() const noexcept
Returns the number of items currently in the array.
ObjectClass * getUnchecked(int index) const noexcept
Returns a pointer to the object at this index in the array, without checking whether the index is in-...
void clear(bool deleteObjects=true)
Clears the array, optionally deleting the objects inside it first.
ObjectClass * insert(int indexToInsertAt, ObjectClass *newObject)
Inserts a new object into the array at the given index.
void setItemLayout(int itemIndex, double minimumSize, double maximumSize, double preferredSize)
For a numbered item, this sets its size limits and preferred size.
int getItemCurrentPosition(int itemIndex) const
Returns the current position of one of the items.
double getItemCurrentRelativeSize(int itemIndex) const
Returns the current size of one of the items.
int getItemCurrentAbsoluteSize(int itemIndex) const
Returns the current size of one of the items.
void clearAllItems()
Clears all the properties that have been set with setItemLayout() and resets this object to its initi...
void layOutComponents(Component **components, int numComponents, int x, int y, int width, int height, bool vertically, bool resizeOtherDimension)
Takes a set of components that correspond to the layout's items, and positions them to fill a space.
bool getItemLayout(int itemIndex, double &minimumSize, double &maximumSize, double &preferredSize) const
For a numbered item, this returns its size limits and preferred size.
void setItemPosition(int itemIndex, int newPosition)
Moves one of the items, shifting along any other items as necessary in order to get it to the desired...
typedef double
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
T size(T... args)