From d2ab30e7a69bfe7efda63ae75812207377917bd3 Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Sun, 30 Mar 2025 18:50:27 +0000 Subject: [PATCH] Merge branch 'Flexalon-UI-Layouts' into develop --- Assets/Flexalon/Runtime/Core/Flex.cs | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 145 insertions(+), 0 deletions(-) diff --git a/Assets/Flexalon/Runtime/Core/Flex.cs b/Assets/Flexalon/Runtime/Core/Flex.cs new file mode 100644 index 0000000..a3523a9 --- /dev/null +++ b/Assets/Flexalon/Runtime/Core/Flex.cs @@ -0,0 +1,145 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace Flexalon +{ + public class FlexItem + { + public float MinSize; + public float MaxSize; + public float StartSize; + public float ShrinkFactor; + public float GrowFactor; + public float FinalSize; + } + + public static class Flex + { + public static void GrowOrShrink(List<FlexItem> items, float usedSpace, float totalSpace, float gap) + { + if (totalSpace > usedSpace) + { + Grow(items, totalSpace, gap); + } + else + { + Shrink(items, totalSpace, gap); + } + } + + public static void Grow(List<FlexItem> items, float space, float gap) + { + space -= gap * (items.Count - 1); + + var totalFactor = 0f; + foreach (var item in items) + { + if (item.GrowFactor == 0) + { + item.FinalSize = Mathf.Clamp(item.StartSize, item.MinSize, item.MaxSize); + } + else if (item.StartSize >= item.MaxSize) + { + item.FinalSize = item.MaxSize; + } + else + { + item.FinalSize = item.StartSize; + totalFactor += item.GrowFactor; + } + + space = Mathf.Max(0, space - item.FinalSize); + } + + var canGrow = totalFactor > 0; + var remaining = space; + while (canGrow) + { + canGrow = false; + foreach (var item in items) + { + if (item.FinalSize < item.MaxSize && item.GrowFactor > 0) + { + if (totalFactor >= 1) + { + item.FinalSize = item.StartSize + remaining * item.GrowFactor * (1 / totalFactor); + } + else + { + item.FinalSize = item.StartSize + space * item.GrowFactor; + } + + if (item.FinalSize > item.MaxSize) + { + item.FinalSize = item.MaxSize; + totalFactor -= item.GrowFactor; + remaining -= item.MaxSize; + canGrow = totalFactor > 0; + } + else if (item.FinalSize < item.MinSize) + { + item.FinalSize = item.MinSize; + totalFactor -= item.GrowFactor; + remaining -= item.MinSize; + canGrow = totalFactor > 0; + item.GrowFactor = 0; + } + } + } + } + } + + public static void Shrink(List<FlexItem> items, float space, float gap) + { + var totalFactor = 0f; + space -= gap * (items.Count - 1); + + foreach (var item in items) + { + item.FinalSize = Mathf.Clamp(item.StartSize, item.MinSize, item.MaxSize); + if (item.FinalSize > item.MinSize && item.ShrinkFactor > 0) + { + totalFactor += item.ShrinkFactor; + } + else + { + space = Mathf.Max(0, space - item.FinalSize); + } + } + + bool canShrink = totalFactor > 0; + while (canShrink) + { + canShrink = false; + foreach (var item in items) + { + if (item.FinalSize > item.MinSize && item.ShrinkFactor > 0) + { + item.FinalSize = space * item.ShrinkFactor * (1 / totalFactor); + if (item.FinalSize < item.MinSize) + { + item.FinalSize = item.MinSize; + space = Mathf.Max(0, space - item.MinSize); + totalFactor -= item.ShrinkFactor; + canShrink = totalFactor > 0; + } + } + } + } + } + + public static FlexItem CreateFlexItem(FlexalonNode node, int axis, float childSize, float usedSize, float layoutSize) + { + var growFactor = node.GetSizeType(axis) == SizeType.Fill ? node.SizeOfParent[axis] : 0; + + return new FlexItem() + { + MinSize = node.GetMinSize(axis, layoutSize), + MaxSize = node.GetMaxSize(axis, layoutSize), + StartSize = growFactor == 0 ? childSize : 0, // Don't support flex-basis + grow + ShrinkFactor = node.CanShrink(axis) ? childSize / usedSize : 0, + GrowFactor = growFactor + }; + } + } +} \ No newline at end of file -- Gitblit v1.9.3