166 |
public static SizeRequirements |
public static SizeRequirements |
167 |
getAlignedSizeRequirements(SizeRequirements[] children) |
getAlignedSizeRequirements(SizeRequirements[] children) |
168 |
{ |
{ |
169 |
return null; // TODO |
float minLeft = 0; |
170 |
|
float minRight = 0; |
171 |
|
float prefLeft = 0; |
172 |
|
float prefRight = 0; |
173 |
|
float maxLeft = 0; |
174 |
|
float maxRight = 0; |
175 |
|
for (int i = 0; i < children.length; i++) |
176 |
|
{ |
177 |
|
float myMinLeft = children[i].minimum * children[i].alignment; |
178 |
|
float myMinRight = children[i].minimum - myMinLeft; |
179 |
|
minLeft = Math.max(myMinLeft, minLeft); |
180 |
|
minRight = Math.max(myMinRight, minRight); |
181 |
|
float myPrefLeft = children[i].preferred * children[i].alignment; |
182 |
|
float myPrefRight = children[i].preferred - myPrefLeft; |
183 |
|
prefLeft = Math.max(myPrefLeft, prefLeft); |
184 |
|
prefRight = Math.max(myPrefRight, prefRight); |
185 |
|
float myMaxLeft = children[i].maximum * children[i].alignment; |
186 |
|
float myMaxRight = children[i].maximum - myMaxLeft; |
187 |
|
maxLeft = Math.max(myMaxLeft, maxLeft); |
188 |
|
maxRight = Math.max(myMaxRight, maxRight); |
189 |
|
} |
190 |
|
int minSize = (int) (minLeft + minRight); |
191 |
|
int prefSize = (int) (prefLeft + prefRight); |
192 |
|
int maxSize = (int) (maxLeft + maxRight); |
193 |
|
float align = prefLeft / (prefRight + prefLeft); |
194 |
|
if (Float.isNaN(align)) |
195 |
|
align = 0; |
196 |
|
return new SizeRequirements(minSize, prefSize, maxSize, align); |
197 |
} |
} |
198 |
|
|
199 |
/** |
/** |
259 |
int[] offsets, int[] spans, |
int[] offsets, int[] spans, |
260 |
boolean forward) |
boolean forward) |
261 |
{ |
{ |
262 |
|
int span = 0; |
263 |
if (forward) |
if (forward) |
264 |
{ |
{ |
265 |
int offset = 0; |
int offset = 0; |
267 |
{ |
{ |
268 |
offsets[i] = offset; |
offsets[i] = offset; |
269 |
spans[i] = children[i].preferred; |
spans[i] = children[i].preferred; |
270 |
|
span += spans[i]; |
271 |
offset += children[i].preferred; |
offset += children[i].preferred; |
272 |
} |
} |
273 |
} |
} |
278 |
{ |
{ |
279 |
offset -= children[i].preferred; |
offset -= children[i].preferred; |
280 |
offsets[i] = offset; |
offsets[i] = offset; |
281 |
|
span += spans[i]; |
282 |
spans[i] = children[i].preferred; |
spans[i] = children[i].preferred; |
283 |
} |
} |
284 |
} |
} |
285 |
|
// Adjust spans so that we exactly fill the allocated region. If |
286 |
|
if (span > allocated) |
287 |
|
adjustSmaller(allocated, children, spans, span); |
288 |
|
else if (span < allocated) |
289 |
|
adjustGreater(allocated, children, spans, span); |
290 |
|
|
291 |
|
// Adjust offsets. |
292 |
|
if (forward) |
293 |
|
{ |
294 |
|
int offset = 0; |
295 |
|
for (int i = 0; i < children.length; i++) |
296 |
|
{ |
297 |
|
offsets[i] = offset; |
298 |
|
offset += spans[i]; |
299 |
|
} |
300 |
|
} |
301 |
|
else |
302 |
|
{ |
303 |
|
int offset = allocated; |
304 |
|
for (int i = 0; i < children.length; i++) |
305 |
|
{ |
306 |
|
offset -= spans[i]; |
307 |
|
offsets[i] = offset; |
308 |
|
} |
309 |
|
} |
310 |
|
} |
311 |
|
|
312 |
|
private static void adjustSmaller(int allocated, SizeRequirements[] children, |
313 |
|
int[] spans, int span) |
314 |
|
{ |
315 |
|
// Sum up (prefSize - minSize) over all children |
316 |
|
int sumDelta = 0; |
317 |
|
for (int i = 0; i < children.length; i++) |
318 |
|
sumDelta += children[i].preferred - children[i].minimum; |
319 |
|
|
320 |
|
// If we have sumDelta == 0, then all components have prefSize == maxSize |
321 |
|
// and we can't do anything about it. |
322 |
|
if (sumDelta == 0) |
323 |
|
return; |
324 |
|
|
325 |
|
// Adjust all sizes according to their preferred and minimum sizes. |
326 |
|
for (int i = 0; i < children.length; i++) |
327 |
|
{ |
328 |
|
double factor = ((double) (children[i].preferred - children[i].minimum)) |
329 |
|
/ ((double) sumDelta); |
330 |
|
// In case we have a sumDelta of 0, the factor should also be 0. |
331 |
|
if (Double.isNaN(factor)) |
332 |
|
factor = 0; |
333 |
|
spans[i] -= factor * (span - allocated); |
334 |
|
} |
335 |
|
} |
336 |
|
|
337 |
|
private static void adjustGreater(int allocated, SizeRequirements[] children, |
338 |
|
int[] spans, int span) |
339 |
|
{ |
340 |
|
// Sum up (maxSize - prefSize) over all children |
341 |
|
int sumDelta = 0; |
342 |
|
for (int i = 0; i < children.length; i++) |
343 |
|
{ |
344 |
|
sumDelta += children[i].maximum - children[i].preferred; |
345 |
|
if (sumDelta < 0) |
346 |
|
sumDelta = Integer.MAX_VALUE; |
347 |
|
} |
348 |
|
|
349 |
|
// If we have sumDelta == 0, then all components have prefSize == maxSize |
350 |
|
// and we can't do anything about it. |
351 |
|
if (sumDelta == 0) |
352 |
|
return; |
353 |
|
|
354 |
|
// Adjust all sizes according to their preferred and minimum sizes. |
355 |
|
for (int i = 0; i < children.length; i++) |
356 |
|
{ |
357 |
|
double factor = ((double) (children[i].maximum - children[i].preferred)) |
358 |
|
/ ((double) sumDelta); |
359 |
|
spans[i] -= factor * (span - allocated); |
360 |
|
} |
361 |
} |
} |
362 |
|
|
363 |
/** |
/** |
423 |
int[] offset, int[] spans, |
int[] offset, int[] spans, |
424 |
boolean forward) |
boolean forward) |
425 |
{ |
{ |
426 |
// TODO: Implement this correctly. |
// First we compute the position of the baseline. |
427 |
for (int i = 0; i < children.length; ++i) |
float baseline = allocated * total.alignment; |
428 |
|
|
429 |
|
// Now we can layout the components along the baseline. |
430 |
|
for (int i = 0; i < children.length; i++) |
431 |
{ |
{ |
432 |
// This is only a hack to make things work a little. |
float align = children[i].alignment; |
433 |
spans[i] = Math.min(allocated, children[i].maximum); |
// Try to fit the component into the available space. |
434 |
|
int[] spanAndOffset = new int[2]; |
435 |
|
if (align < .5F || baseline == 0) |
436 |
|
adjustFromRight(children[i], baseline, allocated, spanAndOffset); |
437 |
|
else |
438 |
|
adjustFromLeft(children[i], baseline, allocated, spanAndOffset); |
439 |
|
spans[i] = spanAndOffset[0]; |
440 |
|
offset[i] = spanAndOffset[1]; |
441 |
} |
} |
442 |
} |
} |
443 |
|
|
444 |
/** |
/** |
445 |
|
* Adjusts the span and offset of a component for the aligned layout. |
446 |
|
* |
447 |
|
* @param reqs |
448 |
|
* @param baseline |
449 |
|
* @param allocated |
450 |
|
* @param spanAndOffset |
451 |
|
*/ |
452 |
|
private static void adjustFromRight(SizeRequirements reqs, float baseline, |
453 |
|
int allocated, int[] spanAndOffset) |
454 |
|
{ |
455 |
|
float right = allocated - baseline; |
456 |
|
// If the resulting span exceeds the maximum of the component, then adjust |
457 |
|
// accordingly. |
458 |
|
float maxRight = ((float) reqs.maximum) * (1.F - reqs.alignment); |
459 |
|
if (right / (1.F - reqs.alignment) > reqs.maximum) |
460 |
|
right = maxRight; |
461 |
|
// If we have not enough space on the left side, then adjust accordingly. |
462 |
|
if (right / (1.F - reqs.alignment) * reqs.alignment > allocated - baseline) |
463 |
|
right = ((float) (allocated - baseline)) |
464 |
|
/ reqs.alignment * (1.F - reqs.alignment); |
465 |
|
|
466 |
|
spanAndOffset[0] = (int) (right / (1.F - reqs.alignment)); |
467 |
|
spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment); |
468 |
|
} |
469 |
|
|
470 |
|
/** |
471 |
|
* Adjusts the span and offset of a component for the aligned layout. |
472 |
|
* |
473 |
|
* @param reqs |
474 |
|
* @param baseline |
475 |
|
* @param allocated |
476 |
|
* @param spanAndOffset |
477 |
|
*/ |
478 |
|
private static void adjustFromLeft(SizeRequirements reqs, float baseline, |
479 |
|
int allocated, int[] spanAndOffset) |
480 |
|
{ |
481 |
|
float left = baseline; |
482 |
|
// If the resulting span exceeds the maximum of the component, then adjust |
483 |
|
// accordingly. |
484 |
|
float maxLeft = ((float) reqs.maximum) * reqs.alignment; |
485 |
|
if (left / reqs.alignment > reqs.maximum) |
486 |
|
left = maxLeft; |
487 |
|
// If we have not enough space on the right side, then adjust accordingly. |
488 |
|
if (left / reqs.alignment * (1.F - reqs.alignment) > allocated - baseline) |
489 |
|
left = ((float) (allocated - baseline)) |
490 |
|
/ (1.F - reqs.alignment) * reqs.alignment; |
491 |
|
|
492 |
|
spanAndOffset[0] = (int) (left / reqs.alignment); |
493 |
|
spanAndOffset[1] = (int) (baseline - spanAndOffset[0] * reqs.alignment); |
494 |
|
} |
495 |
|
|
496 |
|
/** |
497 |
* Returns an array of new preferred sizes for the children based on |
* Returns an array of new preferred sizes for the children based on |
498 |
* <code>delta</code>. <code>delta</code> specifies a change in the |
* <code>delta</code>. <code>delta</code> specifies a change in the |
499 |
* allocated space. The sizes of the children will be shortened or |
* allocated space. The sizes of the children will be shortened or |