Files
Hasebe/Library/PackageCache/com.annulusgames.alchemy@1402075f473d/Editor/BuiltinGroupDrawers.cs
T
2026-09-21 12:15:57 +03:00

234 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Alchemy.Editor.Elements;
using Alchemy.Inspector;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace Alchemy.Editor.Drawers
{
[CustomGroupDrawer(typeof(GroupAttribute))]
public sealed class GroupDrawer : AlchemyGroupDrawer
{
public override VisualElement CreateRootElement(string label)
{
return new Box()
{
style = {
width = Length.Percent(100f),
marginTop = 3f,
paddingBottom = 2f,
paddingRight = 1f,
paddingLeft = 1f,
}
};
}
}
[CustomGroupDrawer(typeof(BoxGroupAttribute))]
public sealed class BoxGroupDrawer : AlchemyGroupDrawer
{
public override VisualElement CreateRootElement(string label)
{
var helpBox = new HelpBox()
{
text = label,
style = {
flexDirection = FlexDirection.Column,
width = Length.Percent(100f),
marginTop = 3f,
paddingBottom = 3f,
paddingRight = 3f,
paddingLeft = 3f,
}
};
var labelElement = helpBox.Q<Label>();
labelElement.style.top = 2f;
labelElement.style.left = 2f;
labelElement.style.fontSize = 12f;
labelElement.style.minHeight = EditorGUIUtility.singleLineHeight;
labelElement.style.unityFontStyleAndWeight = FontStyle.Bold;
labelElement.style.alignSelf = Align.Stretch;
return helpBox;
}
}
[CustomGroupDrawer(typeof(TabGroupAttribute))]
public sealed class TabGroupDrawer : AlchemyGroupDrawer
{
VisualElement rootElement;
readonly Dictionary<string, VisualElement> tabElements = new();
string[] keyArrayCache = new string[0];
int tabIndex;
int prevTabIndex;
sealed class TabItem
{
public string name;
public VisualElement element;
}
public override VisualElement CreateRootElement(string label)
{
var configKey = UniqueId + "_TabGroup";
int.TryParse(EditorUserSettings.GetConfigValue(configKey), out tabIndex);
prevTabIndex = tabIndex;
rootElement = new HelpBox()
{
style = {
flexDirection = FlexDirection.Column,
width = Length.Percent(100f),
marginTop = 3f,
paddingBottom = 3f,
paddingRight = 3f,
paddingLeft = 3f,
}
};
rootElement.Q<Label>()?.RemoveFromHierarchy();
var tabGUIElement = new IMGUIContainer(() =>
{
var rect = EditorGUILayout.GetControlRect();
rect.xMin -= 3.7f;
rect.xMax += 3.7f;
rect.yMin -= 3.7f;
rect.yMax -= 1f;
tabIndex = GUI.Toolbar(rect, tabIndex, keyArrayCache);
if (tabIndex != prevTabIndex)
{
EditorUserSettings.SetConfigValue(configKey, tabIndex.ToString());
prevTabIndex = tabIndex;
}
foreach (var kv in tabElements)
{
kv.Value.style.display = keyArrayCache[tabIndex] == kv.Key ? DisplayStyle.Flex : DisplayStyle.None;
}
})
{
style = {
width = Length.Percent(100f),
marginLeft = 0f,
marginRight = 0f,
marginTop = 0f
}
};
rootElement.Add(tabGUIElement);
return rootElement;
}
public override VisualElement GetGroupElement(Attribute attribute)
{
var tabGroupAttribute = (TabGroupAttribute)attribute;
var tabName = tabGroupAttribute.TabName;
if (!tabElements.TryGetValue(tabName, out var element))
{
element = new VisualElement()
{
style = {
width = Length.Percent(100f)
}
};
rootElement.Add(element);
tabElements.Add(tabName, element);
keyArrayCache = tabElements.Keys.ToArray();
}
return element;
}
}
[CustomGroupDrawer(typeof(FoldoutGroupAttribute))]
public sealed class FoldoutGroupDrawer : AlchemyGroupDrawer
{
public override VisualElement CreateRootElement(string label)
{
var configKey = UniqueId + "_FoldoutGroup";
bool.TryParse(EditorUserSettings.GetConfigValue(configKey), out var result);
var foldout = new Foldout()
{
style = {
width = Length.Percent(100f)
},
text = label,
value = result
};
foldout.RegisterValueChangedCallback(x =>
{
EditorUserSettings.SetConfigValue(configKey, x.newValue.ToString());
});
return foldout;
}
}
[CustomGroupDrawer(typeof(HorizontalGroupAttribute))]
public sealed class HorizontalGroupDrawer : AlchemyGroupDrawer
{
public override VisualElement CreateRootElement(string label)
{
var root = new VisualElement()
{
style = {
width = Length.Percent(100f),
flexDirection = FlexDirection.Row
}
};
static void AdjustLabel(PropertyField element, VisualElement inspector, int childCount)
{
if (element.childCount == 0) return;
if (element.Q<Foldout>() != null) return;
var field = element[0];
field.RemoveFromClassList("unity-base-field__aligned");
var labelElement = field.Q<Label>();
if (labelElement != null)
{
labelElement.style.minWidth = 0f;
labelElement.style.width = GUIHelper.CalculateLabelWidth(element, inspector) * 0.8f / childCount;
}
}
root.schedule.Execute(() =>
{
if (root.childCount <= 1) return;
var visualTree = root.panel.visualTree;
foreach (var field in root.Query<PropertyField>().Build())
{
AdjustLabel(field, visualTree, root.childCount);
}
foreach (var field in root.Query<GenericField>().Children<PropertyField>().Build())
{
AdjustLabel(field, visualTree, root.childCount);
}
});
return root;
}
}
[CustomGroupDrawer(typeof(InlineGroupAttribute))]
public sealed class InlineGroupDrawer : AlchemyGroupDrawer
{
public override VisualElement CreateRootElement(string label)
{
return new VisualElement();
}
}
}