builds
This commit is contained in:
104
Scripts/Helpers/AspectRatioPanel.cs
Normal file
104
Scripts/Helpers/AspectRatioPanel.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
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);
|
||||
}
|
||||
}
|
84
Scripts/Helpers/LabelAutoFit.cs
Normal file
84
Scripts/Helpers/LabelAutoFit.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class LabelAutoFit : Label
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public new class UxmlFactory : UxmlFactory<LabelAutoFit, UxmlTraits> { }
|
||||
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
public new class UxmlTraits : Label.UxmlTraits
|
||||
{
|
||||
readonly UxmlIntAttributeDescription minFontSize = new UxmlIntAttributeDescription
|
||||
{
|
||||
name = "min-font-size",
|
||||
defaultValue = 10,
|
||||
restriction = new UxmlValueBounds { min = "1" }
|
||||
};
|
||||
|
||||
readonly UxmlIntAttributeDescription maxFontSize = new UxmlIntAttributeDescription
|
||||
{
|
||||
name = "max-font-size",
|
||||
defaultValue = 200,
|
||||
restriction = new UxmlValueBounds { min = "1" }
|
||||
};
|
||||
|
||||
public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription { get { yield break; } }
|
||||
|
||||
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
|
||||
{
|
||||
base.Init(ve, bag, cc);
|
||||
|
||||
LabelAutoFit instance = ve as LabelAutoFit;
|
||||
instance.minFontSize = Mathf.Max(minFontSize.GetValueFromBag(bag, cc), 1);
|
||||
instance.maxFontSize = Mathf.Max(maxFontSize.GetValueFromBag(bag, cc), 1);
|
||||
instance.RegisterCallback<GeometryChangedEvent>(instance.OnGeometryChanged);
|
||||
instance.style.fontSize = 1; // Triggers OnGeometryChanged callback
|
||||
}
|
||||
}
|
||||
|
||||
// Setting a limit of max text font refreshes from a single OnGeometryChanged to avoid repeating cycles in some extreme cases
|
||||
private const int MAX_FONT_REFRESHES = 2;
|
||||
|
||||
private int m_textRefreshes = 0;
|
||||
|
||||
public int minFontSize { get; set; }
|
||||
public int maxFontSize { get; set; }
|
||||
|
||||
// Call this if the font size does not update by just setting the text
|
||||
// Should probably wait till the end of frame to get the real font size, instead of using this method
|
||||
// Works well in OnRenderObject() too
|
||||
public void SetText(string text)
|
||||
{
|
||||
this.text = text;
|
||||
UpdateFontSize();
|
||||
}
|
||||
|
||||
private void OnGeometryChanged(GeometryChangedEvent evt)
|
||||
{
|
||||
UpdateFontSize();
|
||||
}
|
||||
|
||||
private void UpdateFontSize()
|
||||
{
|
||||
if (m_textRefreshes < MAX_FONT_REFRESHES)
|
||||
{
|
||||
Vector2 textSize = MeasureTextSize(text, float.MaxValue, MeasureMode.AtMost, float.MaxValue, MeasureMode.AtMost);
|
||||
float fontSize = Mathf.Max(style.fontSize.value.value, 1); // Unity can return a font size of 0 which would break the auto fit // Should probably wait till the end of frame to get the real font size
|
||||
float heightDictatedFontSize = Mathf.Abs(contentRect.height);
|
||||
float widthDictatedFontSize = Mathf.Abs(contentRect.width / textSize.x) * fontSize;
|
||||
float newFontSize = Mathf.FloorToInt(Mathf.Min(heightDictatedFontSize, widthDictatedFontSize));
|
||||
newFontSize = Mathf.Clamp(newFontSize, minFontSize, maxFontSize);
|
||||
if (Mathf.Abs(newFontSize - fontSize) > 1)
|
||||
{
|
||||
m_textRefreshes++;
|
||||
style.fontSize = new StyleLength(new Length(newFontSize));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textRefreshes = 0;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user