r2mods/ilspy_dump/ror2_csproj/RoR2.UI/PieChartMeshController.cs

209 lines
4.8 KiB
C#

using System;
using System.Collections.ObjectModel;
using HG;
using JetBrains.Annotations;
using TMPro;
using UnityEngine;
namespace RoR2.UI;
[ExecuteAlways]
public class PieChartMeshController : MonoBehaviour
{
[Serializable]
public struct SliceInfo : IEquatable<SliceInfo>
{
[Min(0f)]
public float weight;
public Color color;
public TooltipContent tooltipContent;
public bool Equals(SliceInfo other)
{
if (weight.Equals(other.weight) && color.Equals(other.color))
{
return tooltipContent.Equals(other.tooltipContent);
}
return false;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj is SliceInfo other)
{
return Equals(other);
}
return false;
}
public override int GetHashCode()
{
return (((weight.GetHashCode() * 397) ^ color.GetHashCode()) * 397) ^ tooltipContent.GetHashCode();
}
public static bool operator ==(SliceInfo left, SliceInfo right)
{
return left.Equals(right);
}
public static bool operator !=(SliceInfo left, SliceInfo right)
{
return !left.Equals(right);
}
}
public RectTransform container;
public GameObject slicePrefab;
[Range(0f, 1f)]
public float normalizedInnerRadius;
[Tooltip("The minimum value required to display percentage and show an entry in the legend.")]
public float minimumRequiredWeightToDisplay = 0.03f;
public Texture texture;
public Material material;
[ColorUsage(true, true)]
public Color color;
public float uTile = 1f;
public bool individualSegmentUMapping;
[SerializeField]
private int maxSlices = 16;
[SerializeField]
private SliceInfo[] sliceInfos = Array.Empty<SliceInfo>();
private int totalSliceCount;
private UIElementAllocator<RadialSliceGraphic> sliceAllocator;
private bool slicesDirty = true;
public int MaxSlices => maxSlices;
public float totalSliceWeight { get; private set; }
public int sliceCount => sliceInfos.Length;
public event Action onRebuilt;
private void Awake()
{
InitSliceAllocator();
}
private void Update()
{
if (slicesDirty)
{
slicesDirty = false;
RebuildSlices();
}
}
private void OnValidate()
{
InitSliceAllocator();
slicesDirty = true;
}
private void InitSliceAllocator()
{
sliceAllocator = new UIElementAllocator<RadialSliceGraphic>(container, slicePrefab, markElementsUnsavable: true, acquireExistingChildren: true);
}
public void SetSlices([NotNull] SliceInfo[] newSliceInfos)
{
if (!ArrayUtils.SequenceEquals(sliceInfos, newSliceInfos))
{
Array.Resize(ref sliceInfos, newSliceInfos.Length);
Array.Copy(newSliceInfos, sliceInfos, sliceInfos.Length);
slicesDirty = true;
}
}
private void RebuildSlices()
{
totalSliceWeight = 0f;
totalSliceCount = 0;
for (int i = 0; i < sliceInfos.Length; i++)
{
float weight = sliceInfos[i].weight;
if (!(weight <= 0f))
{
totalSliceCount++;
totalSliceWeight += weight;
}
}
sliceAllocator.AllocateElements(totalSliceCount);
Radians left = new Radians(MathF.PI / 2f);
float num = 0f;
ReadOnlyCollection<RadialSliceGraphic> elements = sliceAllocator.elements;
int num2 = 0;
int num3 = 0;
int count = elements.Count;
while (num3 < count)
{
ref SliceInfo reference = ref sliceInfos[num2++];
if (reference.weight <= 0f)
{
continue;
}
float num4 = reference.weight / totalSliceWeight;
Radians right = new Radians(num4 * (MathF.PI * 2f));
Radians radians = left - right;
Radians left2 = new Radians(MathF.PI * 2f);
float num5 = num - num4 * uTile;
RadialSliceGraphic radialSliceGraphic = elements[num3++];
RadialSliceGraphic.DisplayData newDisplayData = new RadialSliceGraphic.DisplayData
{
start = left,
end = radians,
startU = (individualSegmentUMapping ? 0f : num),
endU = (individualSegmentUMapping ? uTile : num5),
normalizedInnerRadius = normalizedInnerRadius
};
float right2 = 720f;
newDisplayData.maxQuadWidth = left2 / right2;
newDisplayData.material = material;
newDisplayData.texture = texture;
newDisplayData.color = reference.color * color;
radialSliceGraphic.SetDisplayData(in newDisplayData);
TooltipProvider component = radialSliceGraphic.GetComponent<TooltipProvider>();
if ((bool)component)
{
component.SetContent(reference.tooltipContent);
}
ChildLocator component2 = radialSliceGraphic.GetComponent<ChildLocator>();
if ((bool)component2)
{
Transform transform = component2.FindChild("SliceCenterStickerLabel");
if ((bool)transform)
{
transform.GetComponent<TMP_Text>().SetText((num4 >= minimumRequiredWeightToDisplay) ? Language.GetStringFormatted("PERCENT_FORMAT", num4) : string.Empty);
}
}
left = radians;
num = num5;
}
this.onRebuilt?.Invoke();
}
public SliceInfo GetSliceInfo(int i)
{
return sliceInfos[i];
}
}