40 const double minimumSize,
41 const double maximumSize,
42 const double preferredSize)
44 auto* layout = getInfoFor (itemIndex);
46 if (layout ==
nullptr)
48 layout =
new ItemLayoutProperties();
49 layout->itemIndex = itemIndex;
52 for (i = 0; i < items.
size(); ++i)
59 layout->minSize = minimumSize;
60 layout->maxSize = maximumSize;
61 layout->preferredSize = preferredSize;
62 layout->currentSize = 0;
68 double& preferredSize)
const
70 if (
auto* layout = getInfoFor (itemIndex))
72 minimumSize = layout->minSize;
73 maximumSize = layout->maxSize;
74 preferredSize = layout->preferredSize;
82void StretchableLayoutManager::setTotalSize (
const int newTotalSize)
84 totalSize = newTotalSize;
86 fitComponentsIntoSpace (0, items.
size(), totalSize, 0);
93 for (
int i = 0; i < itemIndex; ++i)
94 if (
auto* layout = getInfoFor (i))
95 pos += layout->currentSize;
102 if (
auto* layout = getInfoFor (itemIndex))
103 return layout->currentSize;
110 if (
auto* layout = getInfoFor (itemIndex))
111 return -layout->currentSize / (
double) totalSize;
119 for (
int i = items.
size(); --i >= 0;)
123 if (layout->itemIndex == itemIndex)
125 auto realTotalSize =
jmax (totalSize, getMinimumSizeOfItems (0, items.
size()));
126 auto minSizeAfterThisComp = getMinimumSizeOfItems (i, items.
size());
127 auto maxSizeAfterThisComp = getMaximumSizeOfItems (i + 1, items.
size());
129 newPosition =
jmax (newPosition, totalSize - maxSizeAfterThisComp - layout->currentSize);
130 newPosition =
jmin (newPosition, realTotalSize - minSizeAfterThisComp);
132 auto endPos = fitComponentsIntoSpace (0, i, newPosition, 0);
134 endPos += layout->currentSize;
136 fitComponentsIntoSpace (i + 1, items.
size(), totalSize - endPos, endPos);
137 updatePrefSizesToMatchCurrentPositions();
146 int x,
int y,
int w,
int h,
147 const bool vertically,
148 const bool resizeOtherDimension)
150 setTotalSize (vertically ? h : w);
151 int pos = vertically ? y : x;
153 for (
int i = 0; i < numComponents; ++i)
155 if (
auto* layout = getInfoFor (i))
157 if (
auto* c = components[i])
159 if (i == numComponents - 1)
162 if (resizeOtherDimension)
165 c->setBounds (x, pos, w,
jmax (layout->currentSize, h - pos));
167 c->setBounds (pos, y,
jmax (layout->currentSize, w - pos), h);
172 c->setBounds (c->getX(), pos, c->getWidth(),
jmax (layout->currentSize, h - pos));
174 c->setBounds (pos, c->getY(),
jmax (layout->currentSize, w - pos), c->getHeight());
179 if (resizeOtherDimension)
182 c->setBounds (x, pos, w, layout->currentSize);
184 c->setBounds (pos, y, layout->currentSize, h);
189 c->setBounds (c->getX(), pos, c->getWidth(), layout->currentSize);
191 c->setBounds (pos, c->getY(), layout->currentSize, c->getHeight());
196 pos += layout->currentSize;
203StretchableLayoutManager::ItemLayoutProperties* StretchableLayoutManager::getInfoFor (
const int itemIndex)
const
205 for (
auto* i : items)
206 if (i->itemIndex == itemIndex)
212int StretchableLayoutManager::fitComponentsIntoSpace (
const int startIndex,
214 const int availableSpace,
218 double totalIdealSize = 0.0;
219 int totalMinimums = 0;
221 for (
int i = startIndex; i < endIndex; ++i)
225 layout->currentSize = sizeToRealSize (layout->minSize, totalSize);
227 totalMinimums += layout->currentSize;
228 totalIdealSize += sizeToRealSize (layout->preferredSize, totalSize);
231 if (totalIdealSize <= 0)
232 totalIdealSize = 1.0;
235 int extraSpace = availableSpace - totalMinimums;
237 while (extraSpace > 0)
239 int numWantingMoreSpace = 0;
240 int numHavingTakenExtraSpace = 0;
243 for (
int i = startIndex; i < endIndex; ++i)
247 auto sizeWanted = sizeToRealSize (layout->preferredSize, totalSize);
249 auto bestSize =
jlimit (layout->currentSize,
250 jmax (layout->currentSize,
251 sizeToRealSize (layout->maxSize, totalSize)),
252 roundToInt (sizeWanted * availableSpace / totalIdealSize));
254 if (bestSize > layout->currentSize)
255 ++numWantingMoreSpace;
259 for (
int i = startIndex; i < endIndex; ++i)
263 auto sizeWanted = sizeToRealSize (layout->preferredSize, totalSize);
265 auto bestSize =
jlimit (layout->currentSize,
266 jmax (layout->currentSize, sizeToRealSize (layout->maxSize, totalSize)),
267 roundToInt (sizeWanted * availableSpace / totalIdealSize));
269 auto extraWanted = bestSize - layout->currentSize;
273 auto extraAllowed =
jmin (extraWanted,
274 extraSpace /
jmax (1, numWantingMoreSpace));
276 if (extraAllowed > 0)
278 ++numHavingTakenExtraSpace;
279 --numWantingMoreSpace;
281 layout->currentSize += extraAllowed;
282 extraSpace -= extraAllowed;
287 if (numHavingTakenExtraSpace <= 0)
292 for (
int i = startIndex; i < endIndex; ++i)
295 startPos += layout->currentSize;
301int StretchableLayoutManager::getMinimumSizeOfItems (
const int startIndex,
302 const int endIndex)
const
304 int totalMinimums = 0;
306 for (
int i = startIndex; i < endIndex; ++i)
307 totalMinimums += sizeToRealSize (items.
getUnchecked (i)->minSize, totalSize);
309 return totalMinimums;
312int StretchableLayoutManager::getMaximumSizeOfItems (
const int startIndex,
const int endIndex)
const
314 int totalMaximums = 0;
316 for (
int i = startIndex; i < endIndex; ++i)
317 totalMaximums += sizeToRealSize (items.
getUnchecked (i)->maxSize, totalSize);
319 return totalMaximums;
322void StretchableLayoutManager::updatePrefSizesToMatchCurrentPositions()
324 for (
int i = 0; i < items.
size(); ++i)
328 layout->preferredSize
334int StretchableLayoutManager::sizeToRealSize (
double size,
int totalSpace)
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.
~StretchableLayoutManager()
Destructor.
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.
StretchableLayoutManager()
Creates an empty layout.
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...
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.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.