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