using System; using System.Reflection; using Alchemy.Inspector; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UIElements; namespace Alchemy.Editor { internal static class GUIHelper { public static Color LineColor => EditorGUIUtility.isProSkin ? new(0.4f, 0.4f, 0.4f) : new(0.6f, 0.6f, 0.6f); public static Color SubtitleColor => new(0.5f, 0.5f, 0.5f); public static Color TextColor => EditorGUIUtility.isProSkin ? new(0.725f, 0.725f, 0.725f) : new(0.141f, 0.141f, 0.141f); public static float CalculateFieldWidth(VisualElement element, VisualElement root) { var labelWidth = CalculateLabelWidth(element, root); return root.resolvedStyle.width - labelWidth - 27f; } public static float CalculateLabelWidth(VisualElement element, VisualElement root) { // This code is a partial modification of the Label width calculation method actually used inside PropertyField. var num = root.resolvedStyle.paddingLeft; var num2 = 37f; var num3 = 123f; var num4 = element.GetFirstAncestorOfType() == null ? 0f : 15f; var width = root.resolvedStyle.width; var a = width * 0.45f - num2 - num - num4; var b = Mathf.Max(num3 - num - num4, 0f); return Mathf.Max(a, b) + 12f; } public static ListView CreateDefaultListView(string label) { return new ListView() { reorderable = true, reorderMode = ListViewReorderMode.Animated, showBorder = true, showFoldoutHeader = true, headerTitle = label, showAddRemoveFooter = true, fixedItemHeight = 20f, virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight, showAlternatingRowBackgrounds = AlternatingRowBackground.None, }; } public static ListView CreateListViewFromFieldInfo(object target, FieldInfo fieldInfo) { var settings = fieldInfo.GetCustomAttribute(); var listView = new ListView { reorderable = settings == null ? true : settings.Reorderable, reorderMode = settings == null ? ListViewReorderMode.Animated : settings.ReorderMode, showBorder = settings == null ? true : settings.ShowBorder, showFoldoutHeader = settings == null ? true : settings.ShowFoldoutHeader, showBoundCollectionSize = settings == null ? true : (settings.ShowFoldoutHeader && settings.ShowBoundCollectionSize), selectionType = settings == null ? SelectionType.Multiple : settings.SelectionType, showAddRemoveFooter = settings == null ? true : settings.ShowAddRemoveFooter, fixedItemHeight = 20f, virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight, showAlternatingRowBackgrounds = settings == null ? AlternatingRowBackground.None : settings.ShowAlternatingRowBackgrounds, }; var events = fieldInfo.GetCustomAttribute(); if (events != null) { listView.itemsAdded += indices => { if (events.OnItemsAdded == null) return; ReflectionHelper.Invoke(target, events.OnItemsAdded, new object[] { indices }); }; listView.itemsRemoved += indices => { if (events.OnItemsRemoved == null) return; ReflectionHelper.Invoke(target, events.OnItemsRemoved, new object[] { indices }); }; #if UNITY_2022_1_OR_NEWER listView.itemsChosen += items => { if (events.OnItemsChosen == null) return; ReflectionHelper.Invoke(target, events.OnItemsChosen, new object[] { items }); }; #else listView.onItemsChosen += items => { if (events.OnItemsChosen == null) return; ReflectionHelper.Invoke(target, events.OnItemsChosen, new object[] { items }); }; #endif listView.itemIndexChanged += (before, after) => { if (events.OnItemIndexChanged == null) return; ReflectionHelper.Invoke(target, events.OnItemIndexChanged, new object[] { before, after }); }; #if UNITY_2022_1_OR_NEWER listView.selectionChanged += items => { if (events.OnSelectionChanged == null) return; ReflectionHelper.Invoke(target, events.OnSelectionChanged, new object[] { items }); }; listView.selectedIndicesChanged += indices => { if (events.OnSelectedIndicesChanged == null) return; ReflectionHelper.Invoke(target, events.OnSelectedIndicesChanged, new object[] { indices }); }; #else listView.onSelectionChange += items => { if (events.OnSelectionChanged == null) return; ReflectionHelper.Invoke(target, events.OnSelectionChanged, new object[] { items }); }; listView.onSelectedIndicesChange += indices => { if (events.OnSelectedIndicesChanged== null) return; ReflectionHelper.Invoke(target, events.OnSelectedIndicesChanged, new object[] { indices }); }; #endif listView.itemsSourceChanged += () => { if (events.OnItemsSourceChanged == null) return; ReflectionHelper.Invoke(target, events.OnItemsSourceChanged, null); }; } return listView; } public static PropertyField CreateObjectPropertyField(SerializedProperty property, Type type) { Assert.IsTrue(property.propertyType == SerializedPropertyType.ObjectReference); var fieldInfo = property.GetFieldInfo(); var isAssetsOnly = fieldInfo.HasCustomAttribute(); var propertyField = new PropertyField(property); propertyField.RegisterValueChangeCallback(x => { var objectField = propertyField.Q(); if (objectField == null) return; objectField.objectType = type; objectField.allowSceneObjects = !isAssetsOnly; }); return propertyField; } public static void ScheduleAdjustLabelWidth(VisualElement element) { void Adjust(VisualElement visualElement) { var label = element.Q