Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/UX/Library/JsonBasedTable.cs

99 lines
2.2 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
/// <summary>
/// 基于Json的Table生成元素
/// </summary>
public class JsonBasedTable : VisualElement
{
public new class UxmlTraits : VisualElement.UxmlTraits
{
private readonly UxmlStringAttributeDescription m_JsonAttribute = new ()
{
name = "Json"
};
private readonly UxmlBoolAttributeDescription m_allowWarningsAttribute = new ()
{
name = "allowWarnings",
defaultValue = false
};
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var table = (JsonBasedTable)ve;
table.Json = m_JsonAttribute.GetValueFromBag(bag, cc);
table.AllowWarning = m_allowWarningsAttribute.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<JsonBasedTable, UxmlTraits> { }
private string _json;
public string Json
{
get => _json;
set
{
_json = value;
ApplyJson();
}
}
public bool AllowWarning { get; set; }
private readonly List<VisualElement> instanceColumns = new();
private void ApplyJson()
{
try
{
Clear();
style.flexDirection = FlexDirection.Row;
style.justifyContent = Justify.FlexStart;
instanceColumns.Clear();
if (string.IsNullOrEmpty(Json)) return;
var jArray = JArray.Parse(Json);
var colLength = jArray.Max(x => x.Count());
var rowLength = jArray.Count;
for (var i = 0; i < colLength; i++)
{
var newContainer = this.Create<VisualElement>();
newContainer.name = $"{nameof(VisualElement)}-{i}";
instanceColumns.Add(newContainer);
}
for (var y = 0; y < rowLength; y++)
{
var array = jArray[y] as JArray;
for (var x = 0; x < colLength; x++)
{
var instance = instanceColumns[x];
if (x >= array!.Count)
{
instance.Create<VisualElement>();
}
else
{
var label = instance.Create<Label>();
label.text = array[x].ToString();
}
}
}
}
catch (Exception)
{
if (AllowWarning)
throw;
}
}
}
}