Projet-IA-Madelaine/Scripts/Helpers/AspectRatioPanel.cs
2024-06-12 21:03:42 +02:00

105 lines
3.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
[UnityEngine.Scripting.Preserve]
public class AspectRatioPanel : VisualElement
{
[UnityEngine.Scripting.Preserve]
public new class UxmlFactory : UxmlFactory<AspectRatioPanel, UxmlTraits> { }
[UnityEngine.Scripting.Preserve]
public new class UxmlTraits : VisualElement.UxmlTraits
{
readonly UxmlIntAttributeDescription aspectRatioX = new() { name = "aspect-ratio-x", defaultValue = 16, restriction = new UxmlValueBounds { min = "1" } };
readonly UxmlIntAttributeDescription aspectRatioY = new() { name = "aspect-ratio-y", defaultValue = 9, restriction = new UxmlValueBounds { min = "1" } };
readonly UxmlIntAttributeDescription balanceX = new() { name = "balance-x", defaultValue = 50, restriction = new UxmlValueBounds { min = "0", max = "100" } };
readonly UxmlIntAttributeDescription balanceY = new() { name = "balance-y", defaultValue = 50, restriction = new UxmlValueBounds { min = "0", max = "100" } };
public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
get { yield break; }
}
public override void Init(VisualElement visualElement, IUxmlAttributes attributes, CreationContext creationContext)
{
base.Init(visualElement, attributes, creationContext);
var element = visualElement as AspectRatioPanel;
if (element != null)
{
element.AspectRatioX = Mathf.Max(1, aspectRatioX.GetValueFromBag(attributes, creationContext));
element.AspectRatioY = Mathf.Max(1, aspectRatioY.GetValueFromBag(attributes, creationContext));
element.BalanceX = Mathf.Clamp(balanceX.GetValueFromBag(attributes, creationContext), 0, 100);
element.BalanceY = Mathf.Clamp(balanceY.GetValueFromBag(attributes, creationContext), 0, 100);
element.FitToParent();
}
}
}
public int AspectRatioX { get; private set; } = 16;
public int AspectRatioY { get; private set; } = 9;
public int BalanceX { get; private set; } = 50;
public int BalanceY { get; private set; } = 50;
public AspectRatioPanel()
{
style.position = Position.Absolute;
style.left = 0;
style.top = 0;
style.right = StyleKeyword.Undefined;
style.bottom = StyleKeyword.Undefined;
RegisterCallback<AttachToPanelEvent>(OnAttachToPanelEvent);
}
void OnAttachToPanelEvent(AttachToPanelEvent e)
{
parent?.RegisterCallback<GeometryChangedEvent>(OnGeometryChangedEvent);
FitToParent();
}
void OnGeometryChangedEvent(GeometryChangedEvent e)
{
FitToParent();
}
void FitToParent()
{
if (parent == null) return;
var parentW = parent.resolvedStyle.width;
var parentH = parent.resolvedStyle.height;
if (float.IsNaN(parentW) || float.IsNaN(parentH)) return;
style.position = Position.Absolute;
style.left = 0;
style.top = 0;
style.right = StyleKeyword.Undefined;
style.bottom = StyleKeyword.Undefined;
if (AspectRatioX <= 0.0f || AspectRatioY <= 0.0f)
{
style.width = parentW;
style.height = parentH;
return;
}
var ratio = Mathf.Min(parentW / AspectRatioX, parentH / AspectRatioY);
var targetW = Mathf.Floor(AspectRatioX * ratio);
var targetH = Mathf.Floor(AspectRatioY * ratio);
style.width = targetW;
style.height = targetH;
var marginX = parentW - targetW;
var marginY = parentH - targetH;
style.left = Mathf.Floor(marginX * BalanceX / 100.0f);
style.top = Mathf.Floor(marginY * BalanceY / 100.0f);
}
}