mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
TEngine 6
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f915322e2be56345a9d145800f7a0e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,627 @@
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class ReorderableListView : VisualElement
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<ReorderableListView, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 制作元素委托
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public delegate VisualElement MakeElementDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// 绑定元素委托
|
||||
/// </summary>
|
||||
public delegate void BindElementDelegqate(VisualElement element, int index);
|
||||
|
||||
private Foldout _foldout;
|
||||
private ListView _listView;
|
||||
private Label _headerLabel;
|
||||
private Button _addButton;
|
||||
private Button _removeButton;
|
||||
private string _headerName = nameof(ReorderableListView);
|
||||
|
||||
/// <summary>
|
||||
/// 源数据
|
||||
/// </summary>
|
||||
public IList SourceData
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value is ArrayList)
|
||||
throw new Exception($"{nameof(SourceData)} not support {nameof(ArrayList)}");
|
||||
|
||||
_listView.Clear();
|
||||
_listView.ClearSelection();
|
||||
_listView.itemsSource = value;
|
||||
_listView.Rebuild();
|
||||
RefreshFoldoutName();
|
||||
RefreshRemoveButton();
|
||||
}
|
||||
get
|
||||
{
|
||||
return _listView.itemsSource;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 元素固定高度
|
||||
/// </summary>
|
||||
public float ElementHeight
|
||||
{
|
||||
set
|
||||
{
|
||||
_listView.fixedItemHeight = value;
|
||||
_listView.Rebuild();
|
||||
}
|
||||
get
|
||||
{
|
||||
return _listView.fixedItemHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加按钮显隐
|
||||
/// </summary>
|
||||
public bool DisplayAdd
|
||||
{
|
||||
set
|
||||
{
|
||||
UIElementsTools.SetElementVisible(_addButton, value);
|
||||
}
|
||||
get
|
||||
{
|
||||
return _addButton.style.visibility == Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除按钮显隐
|
||||
/// </summary>
|
||||
public bool DisplayRemove
|
||||
{
|
||||
set
|
||||
{
|
||||
UIElementsTools.SetElementVisible(_removeButton, value);
|
||||
}
|
||||
get
|
||||
{
|
||||
return _removeButton.style.visibility == Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标题名称
|
||||
/// </summary>
|
||||
public string HeaderName
|
||||
{
|
||||
set
|
||||
{
|
||||
_headerName = value;
|
||||
RefreshFoldoutName();
|
||||
}
|
||||
get
|
||||
{
|
||||
return _headerName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 制作元素的回调
|
||||
/// </summary>
|
||||
public MakeElementDelegate MakeElementCallback;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定元素的回调
|
||||
/// </summary>
|
||||
public BindElementDelegqate BindElementCallback;
|
||||
|
||||
|
||||
public ReorderableListView()
|
||||
{
|
||||
CreateView(true);
|
||||
}
|
||||
public ReorderableListView(bool foldout)
|
||||
{
|
||||
CreateView(foldout);
|
||||
}
|
||||
private void CreateView(bool foldout)
|
||||
{
|
||||
this.style.flexGrow = 1;
|
||||
this.style.flexShrink = 1;
|
||||
|
||||
// 折叠栏
|
||||
if (foldout)
|
||||
{
|
||||
_foldout = new Foldout();
|
||||
_foldout.style.flexGrow = 1f;
|
||||
_foldout.style.flexShrink = 1f;
|
||||
_foldout.text = $"{nameof(ReorderableListView)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
_headerLabel = new Label();
|
||||
}
|
||||
|
||||
// 列表视图
|
||||
_listView = new ListView();
|
||||
_listView.style.flexGrow = 1;
|
||||
_listView.style.flexShrink = 1;
|
||||
_listView.reorderable = true;
|
||||
_listView.reorderMode = ListViewReorderMode.Animated;
|
||||
_listView.makeItem = MakeListViewElement;
|
||||
_listView.bindItem = BindListViewElement;
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
_listView.selectionChanged += OnSelectionChanged;
|
||||
#elif UNITY_2020_1_OR_NEWER
|
||||
_listView.onSelectionChange += OnSelectionChanged;
|
||||
#else
|
||||
_listView.onSelectionChanged += OnSelectionChanged;
|
||||
#endif
|
||||
|
||||
// 按钮组
|
||||
var buttonContainer = new VisualElement();
|
||||
buttonContainer.style.flexDirection = FlexDirection.RowReverse;
|
||||
|
||||
// 移除按钮
|
||||
_removeButton = new Button();
|
||||
_removeButton.text = " - ";
|
||||
_removeButton.clicked += OnClickRemoveButton;
|
||||
_removeButton.SetEnabled(false);
|
||||
buttonContainer.Add(_removeButton);
|
||||
|
||||
// 增加按钮
|
||||
_addButton = new Button();
|
||||
_addButton.text = " + ";
|
||||
_addButton.clicked += OnClickAddButton;
|
||||
buttonContainer.Add(_addButton);
|
||||
|
||||
// 组织页面
|
||||
if (foldout)
|
||||
{
|
||||
_foldout.Add(_listView);
|
||||
_foldout.Add(buttonContainer);
|
||||
this.Add(_foldout);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Add(_headerLabel);
|
||||
this.Add(_listView);
|
||||
this.Add(buttonContainer);
|
||||
}
|
||||
}
|
||||
private void OnClickAddButton()
|
||||
{
|
||||
if (_listView.itemsSource != null)
|
||||
{
|
||||
object defaultValue = GetElementDefaultValue();
|
||||
_listView.itemsSource.Add(defaultValue);
|
||||
_listView.Rebuild();
|
||||
RefreshFoldoutName();
|
||||
RefreshRemoveButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("The source data is null !");
|
||||
}
|
||||
}
|
||||
private void OnClickRemoveButton()
|
||||
{
|
||||
if (_listView.itemsSource != null)
|
||||
{
|
||||
if (_listView.selectedIndex >= 0)
|
||||
{
|
||||
_listView.itemsSource.RemoveAt(_listView.selectedIndex);
|
||||
_listView.Rebuild();
|
||||
RefreshFoldoutName();
|
||||
RefreshRemoveButton();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("The source data is null !");
|
||||
}
|
||||
}
|
||||
private void OnSelectionChanged(IEnumerable<object> objs)
|
||||
{
|
||||
RefreshRemoveButton();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成元素
|
||||
/// </summary>
|
||||
private VisualElement MakeListViewElement()
|
||||
{
|
||||
if (MakeElementCallback != null)
|
||||
{
|
||||
return MakeElementCallback.Invoke();
|
||||
}
|
||||
|
||||
Type elementType = GetElementType();
|
||||
if (elementType == typeof(string))
|
||||
{
|
||||
TextField textField = new TextField();
|
||||
textField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)textField.userData;
|
||||
_listView.itemsSource[itemIndex] = textField.value;
|
||||
});
|
||||
return textField;
|
||||
}
|
||||
else if (elementType == typeof(int))
|
||||
{
|
||||
IntegerField intField = new IntegerField();
|
||||
intField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)intField.userData;
|
||||
_listView.itemsSource[itemIndex] = intField.value;
|
||||
});
|
||||
return intField;
|
||||
}
|
||||
else if (elementType == typeof(long))
|
||||
{
|
||||
LongField longField = new LongField();
|
||||
longField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)longField.userData;
|
||||
_listView.itemsSource[itemIndex] = longField.value;
|
||||
});
|
||||
return longField;
|
||||
}
|
||||
else if (elementType == typeof(float))
|
||||
{
|
||||
FloatField floatField = new FloatField();
|
||||
floatField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)floatField.userData;
|
||||
_listView.itemsSource[itemIndex] = floatField.value;
|
||||
});
|
||||
return floatField;
|
||||
}
|
||||
else if (elementType == typeof(double))
|
||||
{
|
||||
DoubleField doubleField = new DoubleField();
|
||||
doubleField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)doubleField.userData;
|
||||
_listView.itemsSource[itemIndex] = doubleField.value;
|
||||
});
|
||||
return doubleField;
|
||||
}
|
||||
else if (elementType == typeof(bool))
|
||||
{
|
||||
Toggle toggle = new Toggle();
|
||||
toggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)toggle.userData;
|
||||
_listView.itemsSource[itemIndex] = toggle.value;
|
||||
});
|
||||
return toggle;
|
||||
}
|
||||
else if (elementType == typeof(Hash128))
|
||||
{
|
||||
Hash128Field hash128Field = new Hash128Field();
|
||||
hash128Field.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)hash128Field.userData;
|
||||
_listView.itemsSource[itemIndex] = hash128Field.value;
|
||||
});
|
||||
return hash128Field;
|
||||
}
|
||||
else if (elementType == typeof(Vector2))
|
||||
{
|
||||
Vector2Field vector2Field = new Vector2Field();
|
||||
vector2Field.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)vector2Field.userData;
|
||||
_listView.itemsSource[itemIndex] = vector2Field.value;
|
||||
});
|
||||
return vector2Field;
|
||||
}
|
||||
else if (elementType == typeof(Vector3))
|
||||
{
|
||||
Vector3Field vector3Field = new Vector3Field();
|
||||
vector3Field.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)vector3Field.userData;
|
||||
_listView.itemsSource[itemIndex] = vector3Field.value;
|
||||
});
|
||||
return vector3Field;
|
||||
}
|
||||
else if (elementType == typeof(Vector4))
|
||||
{
|
||||
Vector4Field vector4Field = new Vector4Field();
|
||||
vector4Field.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)vector4Field.userData;
|
||||
_listView.itemsSource[itemIndex] = vector4Field.value;
|
||||
});
|
||||
return vector4Field;
|
||||
}
|
||||
else if (elementType == typeof(Rect))
|
||||
{
|
||||
RectField rectField = new RectField();
|
||||
rectField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)rectField.userData;
|
||||
_listView.itemsSource[itemIndex] = rectField.value;
|
||||
});
|
||||
return rectField;
|
||||
}
|
||||
else if (elementType == typeof(Bounds))
|
||||
{
|
||||
BoundsField boundsField = new BoundsField();
|
||||
boundsField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)boundsField.userData;
|
||||
_listView.itemsSource[itemIndex] = boundsField.value;
|
||||
});
|
||||
return boundsField;
|
||||
}
|
||||
else if (elementType == typeof(Color))
|
||||
{
|
||||
ColorField colorField = new ColorField();
|
||||
colorField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)colorField.userData;
|
||||
_listView.itemsSource[itemIndex] = colorField.value;
|
||||
});
|
||||
return colorField;
|
||||
}
|
||||
else if (elementType == typeof(Gradient))
|
||||
{
|
||||
GradientField gradientField = new GradientField();
|
||||
gradientField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)gradientField.userData;
|
||||
_listView.itemsSource[itemIndex] = gradientField.value;
|
||||
});
|
||||
return gradientField;
|
||||
}
|
||||
else if (elementType == typeof(AnimationCurve))
|
||||
{
|
||||
CurveField curveField = new CurveField();
|
||||
curveField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)curveField.userData;
|
||||
_listView.itemsSource[itemIndex] = curveField.value;
|
||||
});
|
||||
return curveField;
|
||||
}
|
||||
else if (elementType == typeof(UnityEngine.Object))
|
||||
{
|
||||
ObjectField objectField = new ObjectField();
|
||||
objectField.objectType = typeof(UnityEngine.Object);
|
||||
objectField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)objectField.userData;
|
||||
_listView.itemsSource[itemIndex] = objectField.value;
|
||||
});
|
||||
return objectField;
|
||||
}
|
||||
else if (elementType.IsEnum)
|
||||
{
|
||||
EnumField enumField = new EnumField();
|
||||
enumField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
int itemIndex = (int)enumField.userData;
|
||||
_listView.itemsSource[itemIndex] = enumField.value;
|
||||
});
|
||||
return enumField;
|
||||
}
|
||||
else
|
||||
{
|
||||
Label label = new Label();
|
||||
label.text = $"Not support element type : {elementType.Name}";
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定元素
|
||||
/// </summary>
|
||||
private void BindListViewElement(VisualElement listViewElement, int index)
|
||||
{
|
||||
if (BindElementCallback != null)
|
||||
{
|
||||
BindElementCallback.Invoke(listViewElement, index);
|
||||
return;
|
||||
}
|
||||
|
||||
var elementValue = _listView.itemsSource[index];
|
||||
string elementName = GetElementName(index);
|
||||
Type elementType = GetElementType();
|
||||
if (elementType == typeof(string))
|
||||
{
|
||||
TextField textField = listViewElement as TextField;
|
||||
textField.userData = index;
|
||||
textField.label = elementName;
|
||||
textField.SetValueWithoutNotify(elementValue as string);
|
||||
}
|
||||
else if (elementType == typeof(int))
|
||||
{
|
||||
IntegerField intField = listViewElement as IntegerField;
|
||||
intField.userData = index;
|
||||
intField.label = elementName;
|
||||
intField.SetValueWithoutNotify((int)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(long))
|
||||
{
|
||||
LongField longField = listViewElement as LongField;
|
||||
longField.userData = index;
|
||||
longField.label = elementName;
|
||||
longField.SetValueWithoutNotify((long)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(float))
|
||||
{
|
||||
FloatField floatField = listViewElement as FloatField;
|
||||
floatField.userData = index;
|
||||
floatField.label = elementName;
|
||||
floatField.SetValueWithoutNotify((float)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(double))
|
||||
{
|
||||
DoubleField doubleField = listViewElement as DoubleField;
|
||||
doubleField.userData = index;
|
||||
doubleField.label = elementName;
|
||||
doubleField.SetValueWithoutNotify((double)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(bool))
|
||||
{
|
||||
Toggle toggle = listViewElement as Toggle;
|
||||
toggle.userData = index;
|
||||
toggle.label = elementName;
|
||||
toggle.SetValueWithoutNotify((bool)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Hash128))
|
||||
{
|
||||
Hash128Field hash128Field = listViewElement as Hash128Field;
|
||||
hash128Field.userData = index;
|
||||
hash128Field.label = elementName;
|
||||
hash128Field.SetValueWithoutNotify((Hash128)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Vector2))
|
||||
{
|
||||
Vector2Field vector2Field = listViewElement as Vector2Field;
|
||||
vector2Field.userData = index;
|
||||
vector2Field.label = elementName;
|
||||
vector2Field.SetValueWithoutNotify((Vector2)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Vector3))
|
||||
{
|
||||
Vector3Field vector3Field = listViewElement as Vector3Field;
|
||||
vector3Field.userData = index;
|
||||
vector3Field.label = elementName;
|
||||
vector3Field.SetValueWithoutNotify((Vector3)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Vector4))
|
||||
{
|
||||
Vector4Field vector4Field = listViewElement as Vector4Field;
|
||||
vector4Field.userData = index;
|
||||
vector4Field.label = elementName;
|
||||
vector4Field.SetValueWithoutNotify((Vector4)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Rect))
|
||||
{
|
||||
RectField rectField = listViewElement as RectField;
|
||||
rectField.userData = index;
|
||||
rectField.label = elementName;
|
||||
rectField.SetValueWithoutNotify((Rect)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Bounds))
|
||||
{
|
||||
BoundsField boundsField = listViewElement as BoundsField;
|
||||
boundsField.userData = index;
|
||||
boundsField.label = elementName;
|
||||
boundsField.SetValueWithoutNotify((Bounds)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Color))
|
||||
{
|
||||
ColorField colorField = listViewElement as ColorField;
|
||||
colorField.userData = index;
|
||||
colorField.label = elementName;
|
||||
colorField.SetValueWithoutNotify((Color)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(Gradient))
|
||||
{
|
||||
GradientField gradientField = listViewElement as GradientField;
|
||||
gradientField.userData = index;
|
||||
gradientField.label = elementName;
|
||||
gradientField.SetValueWithoutNotify((Gradient)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(AnimationCurve))
|
||||
{
|
||||
CurveField curveField = listViewElement as CurveField;
|
||||
curveField.userData = index;
|
||||
curveField.label = elementName;
|
||||
curveField.SetValueWithoutNotify((AnimationCurve)elementValue);
|
||||
}
|
||||
else if (elementType == typeof(UnityEngine.Object))
|
||||
{
|
||||
ObjectField objectField = listViewElement as ObjectField;
|
||||
objectField.userData = index;
|
||||
objectField.label = elementName;
|
||||
objectField.SetValueWithoutNotify(elementValue as UnityEngine.Object);
|
||||
}
|
||||
else if (elementType.IsEnum)
|
||||
{
|
||||
EnumField enumField = listViewElement as EnumField;
|
||||
enumField.userData = index;
|
||||
enumField.label = elementName;
|
||||
enumField.Init((Enum)elementValue);
|
||||
enumField.SetValueWithoutNotify((Enum)elementValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private Type GetElementType()
|
||||
{
|
||||
Type elementType = _listView.itemsSource.GetType().GetGenericArguments()[0];
|
||||
return elementType;
|
||||
}
|
||||
private object GetElementDefaultValue()
|
||||
{
|
||||
Type type = GetElementType();
|
||||
if (type.IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private string GetElementName(int index)
|
||||
{
|
||||
return $"Element {index}";
|
||||
}
|
||||
|
||||
private void RefreshRemoveButton()
|
||||
{
|
||||
if (_listView.itemsSource == null)
|
||||
{
|
||||
_removeButton.SetEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 注意:数据列表移除元素的时候有可能会越界!
|
||||
if (_listView.selectedIndex >= _listView.itemsSource.Count)
|
||||
_listView.ClearSelection();
|
||||
|
||||
if (_listView.selectedIndex >= 0)
|
||||
_removeButton.SetEnabled(true);
|
||||
else
|
||||
_removeButton.SetEnabled(false);
|
||||
}
|
||||
private void RefreshFoldoutName()
|
||||
{
|
||||
if (_listView.itemsSource == null)
|
||||
{
|
||||
if (_foldout != null)
|
||||
_foldout.text = _headerName;
|
||||
if (_headerLabel != null)
|
||||
_headerLabel.text = _headerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_foldout != null)
|
||||
_foldout.text = _headerName + $" ({_listView.itemsSource.Count}) ";
|
||||
if (_headerLabel != null)
|
||||
_headerLabel.text = _headerName + $" ({_listView.itemsSource.Count}) ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c3f4136cf7142346ae33e8a82cbdb27
|
||||
guid: 111ec0d18888d7e4396b2192f7b4f347
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -0,0 +1,108 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class ResizeHandle : VisualElement
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<ResizeHandle, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private bool _isResizing = false;
|
||||
private float _initialWidth;
|
||||
private Vector2 _initialMousePos;
|
||||
|
||||
/// <summary>
|
||||
/// 控制的UI元素
|
||||
/// </summary>
|
||||
public VisualElement ControlTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制元素的最小宽度
|
||||
/// </summary>
|
||||
public int ControlMinWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制元素的最大宽度
|
||||
/// </summary>
|
||||
public int ControlMaxWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 尺寸发生变化
|
||||
/// </summary>
|
||||
public Action<float> ResizeChanged { get; set; }
|
||||
|
||||
public ResizeHandle()
|
||||
{
|
||||
int defaultWidth = 5;
|
||||
this.style.width = defaultWidth;
|
||||
this.style.minWidth = defaultWidth;
|
||||
this.style.maxWidth = defaultWidth;
|
||||
this.style.opacity = 0;
|
||||
this.style.cursor = UIElementsCursor.CreateCursor(MouseCursor.ResizeHorizontal);
|
||||
|
||||
this.RegisterCallback<MouseDownEvent>(OnMouseDown);
|
||||
this.RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
||||
this.RegisterCallback<MouseUpEvent>(OnMouseUp);
|
||||
}
|
||||
public ResizeHandle(int handleWidth, VisualElement controlTarget, int controlMinWidth, int controlMaxWidth)
|
||||
{
|
||||
ControlTarget = controlTarget;
|
||||
ControlMinWidth = controlMinWidth;
|
||||
ControlMaxWidth = controlMaxWidth;
|
||||
|
||||
this.style.width = handleWidth;
|
||||
this.style.minWidth = handleWidth;
|
||||
this.style.maxWidth = handleWidth;
|
||||
this.style.opacity = 0;
|
||||
this.style.cursor = UIElementsCursor.CreateCursor(MouseCursor.ResizeHorizontal);
|
||||
|
||||
this.RegisterCallback<MouseDownEvent>(OnMouseDown);
|
||||
this.RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
||||
this.RegisterCallback<MouseUpEvent>(OnMouseUp);
|
||||
}
|
||||
|
||||
private void OnMouseDown(MouseDownEvent evt)
|
||||
{
|
||||
// 鼠标左键按下
|
||||
if (ControlTarget != null && evt.button == 0)
|
||||
{
|
||||
_isResizing = true;
|
||||
_initialWidth = ControlTarget.resolvedStyle.width;
|
||||
_initialMousePos = evt.mousePosition;
|
||||
this.CaptureMouse();
|
||||
}
|
||||
}
|
||||
private void OnMouseMove(MouseMoveEvent evt)
|
||||
{
|
||||
if (ControlTarget != null && _isResizing)
|
||||
{
|
||||
// 计算鼠标移动距离
|
||||
float deltaX = evt.mousePosition.x - _initialMousePos.x;
|
||||
|
||||
// 更新控制元素尺寸
|
||||
float newWidth = _initialWidth + deltaX;
|
||||
float width = Mathf.Clamp(newWidth, ControlMinWidth, ControlMaxWidth);
|
||||
ControlTarget.style.width = width;
|
||||
ControlTarget.style.minWidth = width;
|
||||
ControlTarget.style.maxWidth = width;
|
||||
ResizeChanged?.Invoke(width);
|
||||
}
|
||||
}
|
||||
private void OnMouseUp(MouseUpEvent evt)
|
||||
{
|
||||
// 鼠标左键释放
|
||||
if (ControlTarget != null && evt.button == 0)
|
||||
{
|
||||
_isResizing = false;
|
||||
this.ReleaseMouse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: adb565f9b5e9fb3428e54d0cfd58676d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,55 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 显示开关(眼睛图标)
|
||||
/// </summary>
|
||||
public class ToggleDisplay : Toggle
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<ToggleDisplay, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private readonly VisualElement _checkbox;
|
||||
|
||||
public ToggleDisplay()
|
||||
{
|
||||
_checkbox = this.Q<VisualElement>("unity-checkmark");
|
||||
RefreshIcon();
|
||||
}
|
||||
public override void SetValueWithoutNotify(bool newValue)
|
||||
{
|
||||
base.SetValueWithoutNotify(newValue);
|
||||
RefreshIcon();
|
||||
}
|
||||
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
protected override void ToggleValue()
|
||||
{
|
||||
base.ToggleValue();
|
||||
RefreshIcon();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void RefreshIcon()
|
||||
{
|
||||
if (this.value)
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.VisibilityToggleOff).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.VisibilityToggleOn).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 551a9db915a2cf744ac6088e7c634689
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,55 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 折叠开关
|
||||
/// </summary>
|
||||
public class ToggleFoldout : Toggle
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<ToggleFoldout, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private readonly VisualElement _checkbox;
|
||||
|
||||
public ToggleFoldout()
|
||||
{
|
||||
_checkbox = this.Q<VisualElement>("unity-checkmark");
|
||||
RefreshIcon();
|
||||
}
|
||||
public override void SetValueWithoutNotify(bool newValue)
|
||||
{
|
||||
base.SetValueWithoutNotify(newValue);
|
||||
RefreshIcon();
|
||||
}
|
||||
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
protected override void ToggleValue()
|
||||
{
|
||||
base.ToggleValue();
|
||||
RefreshIcon();
|
||||
}
|
||||
#endif
|
||||
|
||||
public void RefreshIcon()
|
||||
{
|
||||
if (this.value)
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.FoldoutOn).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.FoldoutOff).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2619997e70d98794da26a947f9129e25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,55 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 录制开关
|
||||
/// </summary>
|
||||
public class ToggleRecord : Toggle
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<ToggleRecord, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private readonly VisualElement _checkbox;
|
||||
|
||||
public ToggleRecord()
|
||||
{
|
||||
_checkbox = this.Q<VisualElement>("unity-checkmark");
|
||||
RefreshIcon();
|
||||
}
|
||||
public override void SetValueWithoutNotify(bool newValue)
|
||||
{
|
||||
base.SetValueWithoutNotify(newValue);
|
||||
RefreshIcon();
|
||||
}
|
||||
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
protected override void ToggleValue()
|
||||
{
|
||||
base.ToggleValue();
|
||||
RefreshIcon();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void RefreshIcon()
|
||||
{
|
||||
if (this.value)
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.RecordOn).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
var icon = EditorGUIUtility.IconContent(UIElementsIcon.RecordOff).image as Texture2D;
|
||||
_checkbox.style.backgroundImage = icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4eace285493a0844f8a8b8f4a4ea02d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5f8691a7e0c67d4ab790b703925cd75
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,74 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class ColumnStyle
|
||||
{
|
||||
public const float MaxValue = 8388608f;
|
||||
|
||||
/// <summary>
|
||||
/// 单元列宽度
|
||||
/// </summary>
|
||||
public Length Width;
|
||||
|
||||
/// <summary>
|
||||
/// 单元列最小宽度
|
||||
/// </summary>
|
||||
public Length MinWidth;
|
||||
|
||||
/// <summary>
|
||||
/// 单元列最大宽度
|
||||
/// </summary>
|
||||
public Length MaxWidth;
|
||||
|
||||
/// <summary>
|
||||
/// 可伸缩
|
||||
/// </summary>
|
||||
public bool Stretchable = false;
|
||||
|
||||
/// <summary>
|
||||
/// 可搜索
|
||||
/// </summary>
|
||||
public bool Searchable = false;
|
||||
|
||||
/// <summary>
|
||||
/// 可排序
|
||||
/// </summary>
|
||||
public bool Sortable = false;
|
||||
|
||||
/// <summary>
|
||||
/// 统计数量
|
||||
/// </summary>
|
||||
public bool Counter = false;
|
||||
|
||||
/// <summary>
|
||||
/// 展示单位
|
||||
/// </summary>
|
||||
public string Units = string.Empty;
|
||||
|
||||
public ColumnStyle(Length width)
|
||||
{
|
||||
if (width.value > MaxValue)
|
||||
width = MaxValue;
|
||||
|
||||
Width = width;
|
||||
MinWidth = width;
|
||||
MaxWidth = width;
|
||||
}
|
||||
public ColumnStyle(Length width, Length minWidth, Length maxWidth)
|
||||
{
|
||||
if (maxWidth.value > MaxValue)
|
||||
maxWidth = MaxValue;
|
||||
|
||||
Width = width;
|
||||
MinWidth = minWidth;
|
||||
MaxWidth = maxWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a74bbcb5d814f94fb54042ec3b6d94c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b25809b75e1e7141aff3c2011845aab
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,33 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class AssetPathCell : StringValueCell
|
||||
{
|
||||
public AssetPathCell(string searchTag, object cellValue) : base(searchTag, cellValue)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检视资源对象
|
||||
/// Ping an asset object in the Scene like clicking it in an inspector.
|
||||
/// </summary>
|
||||
public bool PingAssetObject()
|
||||
{
|
||||
var assetPath = StringValue;
|
||||
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
|
||||
if (string.IsNullOrEmpty(assetGUID))
|
||||
return false;
|
||||
|
||||
UnityEngine.Object asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
|
||||
if (asset == null)
|
||||
return false;
|
||||
|
||||
Selection.activeObject = asset;
|
||||
EditorGUIUtility.PingObject(asset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed1c077653e577846ba29aadb91f13ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class BooleanValueCell : ITableCell, IComparable
|
||||
{
|
||||
public object CellValue { set; get; }
|
||||
public string SearchTag { private set; get; }
|
||||
public bool BooleanValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)CellValue;
|
||||
}
|
||||
}
|
||||
|
||||
public BooleanValueCell(string searchTag, object cellValue)
|
||||
{
|
||||
SearchTag = searchTag;
|
||||
CellValue = cellValue;
|
||||
}
|
||||
public object GetDisplayObject()
|
||||
{
|
||||
return CellValue.ToString();
|
||||
}
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
if (other is BooleanValueCell cell)
|
||||
{
|
||||
return this.BooleanValue.CompareTo(cell.BooleanValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7b1e743b81646b49b2c05721edcf9b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,25 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class ButtonCell : ITableCell, IComparable
|
||||
{
|
||||
public object CellValue { set; get; }
|
||||
public string SearchTag { private set; get; }
|
||||
|
||||
public ButtonCell(string searchTag)
|
||||
{
|
||||
SearchTag = searchTag;
|
||||
}
|
||||
public object GetDisplayObject()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe6c2551d70d6934da0b6afce3f1062c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class IntegerValueCell : ITableCell, IComparable
|
||||
{
|
||||
public object CellValue { set; get; }
|
||||
public string SearchTag { private set; get; }
|
||||
public long IntegerValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (long)CellValue;
|
||||
}
|
||||
}
|
||||
|
||||
public IntegerValueCell(string searchTag, object cellValue)
|
||||
{
|
||||
SearchTag = searchTag;
|
||||
CellValue = cellValue;
|
||||
}
|
||||
public object GetDisplayObject()
|
||||
{
|
||||
return CellValue.ToString();
|
||||
}
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
if (other is IntegerValueCell cell)
|
||||
{
|
||||
return this.IntegerValue.CompareTo(cell.IntegerValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be8ecb3981efa744f89ee5d3c9e7b7ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class SingleValueCell : ITableCell, IComparable
|
||||
{
|
||||
public object CellValue { set; get; }
|
||||
public string SearchTag { private set; get; }
|
||||
public double SingleValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)CellValue;
|
||||
}
|
||||
}
|
||||
|
||||
public SingleValueCell(string searchTag, object cellValue)
|
||||
{
|
||||
SearchTag = searchTag;
|
||||
CellValue = cellValue;
|
||||
}
|
||||
public object GetDisplayObject()
|
||||
{
|
||||
return CellValue.ToString();
|
||||
}
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
if (other is SingleValueCell cell)
|
||||
{
|
||||
return this.SingleValue.CompareTo(cell.SingleValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae299b7a930e03f458977750de9ca18e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,40 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class StringValueCell : ITableCell, IComparable
|
||||
{
|
||||
public object CellValue { set; get; }
|
||||
public string SearchTag { private set; get; }
|
||||
public string StringValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)CellValue;
|
||||
}
|
||||
}
|
||||
|
||||
public StringValueCell(string searchTag, object cellValue)
|
||||
{
|
||||
SearchTag = searchTag;
|
||||
CellValue = cellValue;
|
||||
}
|
||||
public object GetDisplayObject()
|
||||
{
|
||||
return CellValue;
|
||||
}
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
if (other is StringValueCell cell)
|
||||
{
|
||||
return this.StringValue.CompareTo(cell.StringValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a04fd2585c5538547b9755673aea76df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f347ad29484952842a01a1489fbbef5d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,62 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class DefaultTableData : ITableData
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否可见
|
||||
/// </summary>
|
||||
public bool Visible { set; get; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 单元格集合
|
||||
/// </summary>
|
||||
public IList<ITableCell> Cells { set; get; } = new List<ITableCell>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加单元格数据
|
||||
/// </summary>
|
||||
public void AddCell(ITableCell cell)
|
||||
{
|
||||
Cells.Add(cell);
|
||||
}
|
||||
|
||||
#region 添加默认的单元格数据
|
||||
public void AddButtonCell(string searchTag)
|
||||
{
|
||||
var cell = new ButtonCell(searchTag);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddAssetPathCell(string searchTag, string path)
|
||||
{
|
||||
var cell = new AssetPathCell(searchTag, path);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddStringValueCell(string searchTag, string value)
|
||||
{
|
||||
var cell = new StringValueCell(searchTag, value);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddLongValueCell(string searchTag, long value)
|
||||
{
|
||||
var cell = new IntegerValueCell(searchTag, value);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddDoubleValueCell(string searchTag, double value)
|
||||
{
|
||||
var cell = new SingleValueCell(searchTag, value);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddBoolValueCell(string searchTag, bool value)
|
||||
{
|
||||
var cell = new BooleanValueCell(searchTag, value);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b93bf9f1eb7024c44a1c84b299dc9622
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,18 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public interface ITableCell
|
||||
{
|
||||
/// <summary>
|
||||
/// 单元格数值
|
||||
/// </summary>
|
||||
object CellValue { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取界面显示对象
|
||||
/// </summary>
|
||||
object GetDisplayObject();
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcfa4e21884025c4b91db2efd543e139
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,20 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public interface ITableData
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否可见
|
||||
/// </summary>
|
||||
bool Visible { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 单元格集合
|
||||
/// </summary>
|
||||
IList<ITableCell> Cells { set; get; }
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26779163e1da1ca46948287a4cc10023
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 211ee819fabdd6d4399b79e6fcf45e5c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,229 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public static class DefaultSearchSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析搜索命令
|
||||
/// </summary>
|
||||
public static List<ISearchCommand> ParseCommand(string commandContent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(commandContent))
|
||||
return new List<ISearchCommand>();
|
||||
|
||||
List<ISearchCommand> results = new List<ISearchCommand>(10);
|
||||
string[] commands = Regex.Split(commandContent, @"\s+");
|
||||
foreach (var command in commands)
|
||||
{
|
||||
if (command.Contains("!="))
|
||||
{
|
||||
var splits = command.Split(new string[] { "!=" }, StringSplitOptions.None);
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = "!=";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains(">="))
|
||||
{
|
||||
var splits = command.Split(new string[] { ">=" }, StringSplitOptions.None);
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = ">=";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains("<="))
|
||||
{
|
||||
var splits = command.Split(new string[] { "<=" }, StringSplitOptions.None);
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = "<=";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains(">"))
|
||||
{
|
||||
var splits = command.Split('>');
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = ">";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains("<"))
|
||||
{
|
||||
var splits = command.Split('<');
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = "<";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains("="))
|
||||
{
|
||||
var splits = command.Split('=');
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchCompare();
|
||||
cmd.HeaderTitle = splits[0];
|
||||
cmd.CompareValue = splits[1];
|
||||
cmd.CompareOperator = "=";
|
||||
results.Add(cmd);
|
||||
}
|
||||
else if (command.Contains(":"))
|
||||
{
|
||||
var splits = command.Split(':');
|
||||
if (CheckSplitsValid(command, splits) == false)
|
||||
continue;
|
||||
|
||||
var cmd = new SearchKeyword();
|
||||
cmd.SearchTag = splits[0];
|
||||
cmd.Keyword = splits[1];
|
||||
results.Add(cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cmd = new SearchKeyword();
|
||||
cmd.SearchTag = string.Empty;
|
||||
cmd.Keyword = command;
|
||||
results.Add(cmd);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
private static bool CheckSplitsValid(string command, string[] splits)
|
||||
{
|
||||
if (splits.Length != 2)
|
||||
{
|
||||
Debug.LogWarning($"Invalid search command : {command}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(splits[0]))
|
||||
return false;
|
||||
if (string.IsNullOrEmpty(splits[1]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索匹配
|
||||
/// </summary>
|
||||
public static void Search(List<ITableData> sourceDatas, string command)
|
||||
{
|
||||
var searchCmds = ParseCommand(command);
|
||||
foreach (var tableData in sourceDatas)
|
||||
{
|
||||
tableData.Visible = Search(tableData, searchCmds);
|
||||
}
|
||||
}
|
||||
private static bool Search(ITableData tableData, List<ISearchCommand> commands)
|
||||
{
|
||||
if (commands.Count == 0)
|
||||
return true;
|
||||
|
||||
// 先匹配字符串
|
||||
var searchKeywordCmds = commands.Where(cmd => cmd is SearchKeyword).ToList();
|
||||
if (SearchKeyword(tableData, searchKeywordCmds) == false)
|
||||
return false;
|
||||
|
||||
// 后匹配数值
|
||||
var searchCompareCmds = commands.Where(cmd => cmd is SearchCompare).ToList();
|
||||
if (SearchCompare(tableData, searchCompareCmds) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
private static bool SearchKeyword(ITableData tableData, List<ISearchCommand> commands)
|
||||
{
|
||||
if (commands.Count == 0)
|
||||
return true;
|
||||
|
||||
// 匹配规则:任意字符串列匹配成果
|
||||
foreach (var tableCell in tableData.Cells)
|
||||
{
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
var searchKeywordCmd = cmd as SearchKeyword;
|
||||
if (tableCell is StringValueCell stringValueCell)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchKeywordCmd.SearchTag) == false)
|
||||
{
|
||||
if (searchKeywordCmd.SearchTag == stringValueCell.SearchTag)
|
||||
{
|
||||
if (searchKeywordCmd.CompareTo(stringValueCell.StringValue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (searchKeywordCmd.CompareTo(stringValueCell.StringValue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配失败
|
||||
return false;
|
||||
}
|
||||
private static bool SearchCompare(ITableData tableData, List<ISearchCommand> commands)
|
||||
{
|
||||
if (commands.Count == 0)
|
||||
return true;
|
||||
|
||||
// 匹配规则:任意指定数值列匹配成果
|
||||
foreach (var tableCell in tableData.Cells)
|
||||
{
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
var searchCompareCmd = cmd as SearchCompare;
|
||||
if (tableCell is IntegerValueCell integerValueCell)
|
||||
{
|
||||
if (searchCompareCmd.HeaderTitle == integerValueCell.SearchTag)
|
||||
{
|
||||
if (searchCompareCmd.CompareTo(integerValueCell.IntegerValue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (tableCell is SingleValueCell singleValueCell)
|
||||
{
|
||||
if (searchCompareCmd.HeaderTitle == singleValueCell.SearchTag)
|
||||
{
|
||||
if (searchCompareCmd.CompareTo(singleValueCell.SingleValue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配失败
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3de1e93052c2c86408ba77125da962cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public interface ISearchCommand
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4228528e243224045863d8ae14a16194
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,133 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 指定标题的比较搜索
|
||||
/// </summary>
|
||||
public class SearchCompare : ISearchCommand
|
||||
{
|
||||
public string HeaderTitle;
|
||||
public string CompareValue;
|
||||
public string CompareOperator;
|
||||
|
||||
/// <summary>
|
||||
/// 转换的整形数值
|
||||
/// </summary>
|
||||
private bool _isConvertedIntegerNum = false;
|
||||
private long _convertedIntegerNumber = 0;
|
||||
public long IntegerNumberValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isConvertedIntegerNum == false)
|
||||
{
|
||||
_isConvertedIntegerNum = true;
|
||||
_convertedIntegerNumber = long.Parse(CompareValue.ToString());
|
||||
}
|
||||
return _convertedIntegerNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换的浮点数值
|
||||
/// </summary>
|
||||
private bool _isConvertedSingleNum = false;
|
||||
private double _convertedSingleNumber = 0;
|
||||
public double SingleNumberValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isConvertedSingleNum == false)
|
||||
{
|
||||
_isConvertedSingleNum = true;
|
||||
_convertedSingleNumber = double.Parse(CompareValue.ToString());
|
||||
}
|
||||
return _convertedSingleNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CompareTo(long value)
|
||||
{
|
||||
if (CompareOperator == ">")
|
||||
{
|
||||
if (value > SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == ">=")
|
||||
{
|
||||
if (value >= SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "<")
|
||||
{
|
||||
if (value < SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "<=")
|
||||
{
|
||||
if (value <= SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "=")
|
||||
{
|
||||
if (value == SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "!=")
|
||||
{
|
||||
if (value != SingleNumberValue)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Can not support operator : {CompareOperator}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public bool CompareTo(double value)
|
||||
{
|
||||
if (CompareOperator == ">")
|
||||
{
|
||||
if (value > IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == ">=")
|
||||
{
|
||||
if (value >= IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "<")
|
||||
{
|
||||
if (value < IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "<=")
|
||||
{
|
||||
if (value <= IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "=")
|
||||
{
|
||||
if (value == IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else if (CompareOperator == "!=")
|
||||
{
|
||||
if (value != IntegerNumberValue)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Can not support operator : {CompareOperator}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 345cafa16ea7ccc488c96af1a4ca33c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,19 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 搜索关键字
|
||||
/// </summary>
|
||||
public class SearchKeyword : ISearchCommand
|
||||
{
|
||||
public string SearchTag;
|
||||
public string Keyword;
|
||||
|
||||
public bool CompareTo(string value)
|
||||
{
|
||||
return value.Contains(Keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c34fa79e35e66247b64f18eafa1d230
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,56 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class TableColumn
|
||||
{
|
||||
/// <summary>
|
||||
/// 单元列索引值
|
||||
/// </summary>
|
||||
internal int ColumnIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 单元元素集合
|
||||
/// </summary>
|
||||
internal List<VisualElement> CellElements = new List<VisualElement>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// UI元素名称
|
||||
/// </summary>
|
||||
public string ElementName { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题名称
|
||||
/// </summary>
|
||||
public string HeaderTitle { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 单元列样式
|
||||
/// </summary>
|
||||
public ColumnStyle ColumnStyle { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 制作单元格元素
|
||||
/// </summary>
|
||||
public Func<VisualElement> MakeCell;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定数据到单元格
|
||||
/// </summary>
|
||||
public Action<VisualElement, ITableData, ITableCell> BindCell;
|
||||
|
||||
public TableColumn(string elementName, string headerTitle, ColumnStyle columnStyle)
|
||||
{
|
||||
this.ElementName = elementName;
|
||||
this.HeaderTitle = headerTitle;
|
||||
this.ColumnStyle = columnStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 034395dad363e3a4da96881de60918a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,386 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Unity2022版本以上推荐官方类:MultiColumnListView组件
|
||||
/// </summary>
|
||||
public class TableViewer : VisualElement
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<TableViewer, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private readonly Toolbar _toolbar;
|
||||
private readonly ListView _listView;
|
||||
|
||||
private readonly List<TableColumn> _columns = new List<TableColumn>(10);
|
||||
private List<ITableData> _itemsSource;
|
||||
private List<ITableData> _sortingDatas;
|
||||
|
||||
// 排序相关
|
||||
private string _sortingHeader;
|
||||
private bool _descendingSort = true;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源
|
||||
/// </summary>
|
||||
public List<ITableData> itemsSource
|
||||
{
|
||||
get
|
||||
{
|
||||
return _itemsSource;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (CheckItemsSource(value))
|
||||
{
|
||||
_itemsSource = value;
|
||||
_sortingDatas = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中的数据列表
|
||||
/// </summary>
|
||||
public List<ITableData> selectedItems
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
return _listView.selectedItems.Cast<ITableData>().ToList();
|
||||
#else
|
||||
List<ITableData> result = new List<ITableData>();
|
||||
result.Add(_listView.selectedItem as ITableData);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单元视图交互事件
|
||||
/// </summary>
|
||||
public Action<PointerDownEvent, ITableData> ClickTableDataEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 单元视图交互事件
|
||||
/// </summary>
|
||||
public Action<TableColumn> ClickTableHeadEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 单元视图变化事件
|
||||
/// </summary>
|
||||
public Action<ITableData> SelectionChangedEvent;
|
||||
|
||||
|
||||
public TableViewer()
|
||||
{
|
||||
this.style.flexShrink = 1f;
|
||||
this.style.flexGrow = 1f;
|
||||
|
||||
// 定义标题栏
|
||||
_toolbar = new Toolbar();
|
||||
|
||||
// 定义列表视图
|
||||
_listView = new ListView();
|
||||
_listView.style.flexShrink = 1f;
|
||||
_listView.style.flexGrow = 1f;
|
||||
_listView.makeItem = MakeListViewElement;
|
||||
_listView.bindItem = BindListViewElement;
|
||||
_listView.selectionType = SelectionType.Multiple;
|
||||
_listView.RegisterCallback<PointerDownEvent>(OnClickListItem);
|
||||
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
_listView.selectionChanged += OnSelectionChanged;
|
||||
#elif UNITY_2020_1_OR_NEWER
|
||||
_listView.onSelectionChange += OnSelectionChanged;
|
||||
#else
|
||||
_listView.onSelectionChanged += OnSelectionChanged;
|
||||
#endif
|
||||
|
||||
this.Add(_toolbar);
|
||||
this.Add(_listView);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取标题UI元素
|
||||
/// </summary>
|
||||
public VisualElement GetHeaderElement(string elementName)
|
||||
{
|
||||
return _toolbar.Q<ToolbarButton>(elementName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加单元列
|
||||
/// </summary>
|
||||
public void AddColumn(TableColumn column)
|
||||
{
|
||||
var toolbarBtn = new ToolbarButton();
|
||||
toolbarBtn.userData = column;
|
||||
toolbarBtn.name = column.ElementName;
|
||||
toolbarBtn.text = column.HeaderTitle;
|
||||
toolbarBtn.style.flexGrow = 0;
|
||||
toolbarBtn.style.width = column.ColumnStyle.Width;
|
||||
toolbarBtn.style.minWidth = column.ColumnStyle.Width;
|
||||
toolbarBtn.style.maxWidth = column.ColumnStyle.Width;
|
||||
toolbarBtn.clickable.clickedWithEventInfo += OnClickTableHead;
|
||||
SetCellElementStyle(toolbarBtn);
|
||||
_toolbar.Add(toolbarBtn);
|
||||
_columns.Add(column);
|
||||
|
||||
// 可伸缩控制柄
|
||||
if (column.ColumnStyle.Stretchable)
|
||||
{
|
||||
int handleWidth = 3;
|
||||
int minWidth = (int)column.ColumnStyle.MinWidth.value;
|
||||
int maxWidth = (int)column.ColumnStyle.MaxWidth.value;
|
||||
var resizeHandle = new ResizeHandle(handleWidth, toolbarBtn, minWidth, maxWidth);
|
||||
resizeHandle.ResizeChanged += (float value) =>
|
||||
{
|
||||
float width = Mathf.Clamp(value, column.ColumnStyle.MinWidth.value, column.ColumnStyle.MaxWidth.value);
|
||||
column.ColumnStyle.Width = width;
|
||||
|
||||
foreach (var element in column.CellElements)
|
||||
{
|
||||
element.style.width = width;
|
||||
element.style.minWidth = width;
|
||||
element.style.maxWidth = width;
|
||||
}
|
||||
};
|
||||
_toolbar.Add(resizeHandle);
|
||||
}
|
||||
|
||||
// 计算索引值
|
||||
column.ColumnIndex = _columns.Count - 1;
|
||||
|
||||
if (column.ColumnStyle.Sortable == false)
|
||||
toolbarBtn.SetEnabled(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加单元列集合
|
||||
/// </summary>
|
||||
public void AddColumns(IList<TableColumn> columns)
|
||||
{
|
||||
foreach (var column in columns)
|
||||
{
|
||||
AddColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重建表格视图
|
||||
/// </summary>
|
||||
public void RebuildView()
|
||||
{
|
||||
if (_itemsSource == null)
|
||||
return;
|
||||
|
||||
var itemsSource = _sortingDatas.Where(row => row.Visible);
|
||||
|
||||
_listView.Clear();
|
||||
_listView.ClearSelection();
|
||||
_listView.itemsSource = itemsSource.ToList();
|
||||
_listView.Rebuild();
|
||||
|
||||
// 刷新标题栏
|
||||
RefreshToobar();
|
||||
}
|
||||
private void RefreshToobar()
|
||||
{
|
||||
// 设置为原始标题
|
||||
foreach (var column in _columns)
|
||||
{
|
||||
var toobarButton = _toolbar.Q<ToolbarButton>(column.ElementName);
|
||||
toobarButton.text = column.HeaderTitle;
|
||||
}
|
||||
|
||||
// 设置元素数量
|
||||
foreach (var column in _columns)
|
||||
{
|
||||
if (column.ColumnStyle.Counter)
|
||||
{
|
||||
var toobarButton = GetHeaderElement(column.ElementName) as ToolbarButton;
|
||||
toobarButton.text = $"{toobarButton.text} ({itemsSource.Count()})";
|
||||
}
|
||||
}
|
||||
|
||||
// 设置展示单位
|
||||
foreach (var column in _columns)
|
||||
{
|
||||
if (string.IsNullOrEmpty(column.ColumnStyle.Units) == false)
|
||||
{
|
||||
var toobarButton = GetHeaderElement(column.ElementName) as ToolbarButton;
|
||||
toobarButton.text = $"{toobarButton.text} ({column.ColumnStyle.Units})";
|
||||
}
|
||||
}
|
||||
|
||||
// 设置升降符号
|
||||
if (string.IsNullOrEmpty(_sortingHeader) == false)
|
||||
{
|
||||
var _toobarButton = _toolbar.Q<ToolbarButton>(_sortingHeader);
|
||||
if (_descendingSort)
|
||||
_toobarButton.text = $"{_toobarButton.text} ↓";
|
||||
else
|
||||
_toobarButton.text = $"{_toobarButton.text} ↑";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据
|
||||
/// </summary>
|
||||
public void ClearAll(bool clearColumns, bool clearSource)
|
||||
{
|
||||
if (clearColumns)
|
||||
{
|
||||
_columns.Clear();
|
||||
_toolbar.Clear();
|
||||
}
|
||||
|
||||
if (clearSource)
|
||||
{
|
||||
if (_itemsSource != null)
|
||||
_itemsSource.Clear();
|
||||
if (_sortingDatas != null)
|
||||
_sortingDatas.Clear();
|
||||
_listView.Clear();
|
||||
_listView.ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickListItem(PointerDownEvent evt)
|
||||
{
|
||||
var selectData = _listView.selectedItem as ITableData;
|
||||
if (selectData == null)
|
||||
return;
|
||||
|
||||
ClickTableDataEvent?.Invoke(evt, selectData);
|
||||
}
|
||||
private void OnClickTableHead(EventBase eventBase)
|
||||
{
|
||||
if (_itemsSource == null)
|
||||
return;
|
||||
|
||||
ToolbarButton toolbarBtn = eventBase.target as ToolbarButton;
|
||||
var clickedColumn = toolbarBtn.userData as TableColumn;
|
||||
if (clickedColumn == null)
|
||||
return;
|
||||
|
||||
ClickTableHeadEvent?.Invoke(clickedColumn);
|
||||
if (clickedColumn.ColumnStyle.Sortable == false)
|
||||
return;
|
||||
|
||||
if (_sortingHeader != clickedColumn.ElementName)
|
||||
{
|
||||
_sortingHeader = clickedColumn.ElementName;
|
||||
_descendingSort = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_descendingSort = !_descendingSort;
|
||||
}
|
||||
|
||||
// 升降排序
|
||||
if (_descendingSort)
|
||||
_sortingDatas = _itemsSource.OrderByDescending(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
|
||||
else
|
||||
_sortingDatas = _itemsSource.OrderBy(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
|
||||
|
||||
// 刷新数据表
|
||||
RebuildView();
|
||||
}
|
||||
private void OnSelectionChanged(IEnumerable<object> items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
var tableData = item as ITableData;
|
||||
SelectionChangedEvent?.Invoke(tableData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckItemsSource(List<ITableData> itemsSource)
|
||||
{
|
||||
if (itemsSource == null)
|
||||
return false;
|
||||
|
||||
if (itemsSource.Count > 0)
|
||||
{
|
||||
int cellCount = itemsSource[0].Cells.Count;
|
||||
for (int i = 0; i < itemsSource.Count; i++)
|
||||
{
|
||||
var tableData = itemsSource[i];
|
||||
if (tableData == null)
|
||||
{
|
||||
Debug.LogWarning($"Items source has null instance !");
|
||||
return false;
|
||||
}
|
||||
if (tableData.Cells == null || tableData.Cells.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"Items source data has empty cells !");
|
||||
return false;
|
||||
}
|
||||
if (tableData.Cells.Count != cellCount)
|
||||
{
|
||||
Debug.LogWarning($"Items source data has inconsisten cells count ! Item index {i}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private VisualElement MakeListViewElement()
|
||||
{
|
||||
VisualElement listViewElement = new VisualElement();
|
||||
listViewElement.style.flexDirection = FlexDirection.Row;
|
||||
foreach (var column in _columns)
|
||||
{
|
||||
var cellElement = column.MakeCell.Invoke();
|
||||
cellElement.name = column.ElementName;
|
||||
cellElement.style.flexGrow = 0f;
|
||||
cellElement.style.width = column.ColumnStyle.Width;
|
||||
cellElement.style.minWidth = column.ColumnStyle.Width;
|
||||
cellElement.style.maxWidth = column.ColumnStyle.Width;
|
||||
SetCellElementStyle(cellElement);
|
||||
listViewElement.Add(cellElement);
|
||||
column.CellElements.Add(cellElement);
|
||||
}
|
||||
return listViewElement;
|
||||
}
|
||||
private void BindListViewElement(VisualElement listViewElement, int index)
|
||||
{
|
||||
var sourceDatas = _listView.itemsSource as List<ITableData>;
|
||||
var tableData = sourceDatas[index];
|
||||
foreach (var colum in _columns)
|
||||
{
|
||||
var cellElement = listViewElement.Q(colum.ElementName);
|
||||
var tableCell = tableData.Cells[colum.ColumnIndex];
|
||||
colum.BindCell.Invoke(cellElement, tableData, tableCell);
|
||||
}
|
||||
}
|
||||
private void SetCellElementStyle(VisualElement element)
|
||||
{
|
||||
StyleLength defaultStyle = new StyleLength(1f);
|
||||
element.style.paddingTop = defaultStyle;
|
||||
element.style.paddingBottom = defaultStyle;
|
||||
element.style.marginTop = defaultStyle;
|
||||
element.style.marginBottom = defaultStyle;
|
||||
|
||||
element.style.paddingLeft = 1;
|
||||
element.style.paddingRight = 1;
|
||||
element.style.marginLeft = 0;
|
||||
element.style.marginRight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c12f27850c4d104db1dc85cf532e586
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1797f960cdbd5aa41a96bb02d16c4998
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,77 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class TreeNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 子节点集合
|
||||
/// </summary>
|
||||
public List<TreeNode> Children = new List<TreeNode>(10);
|
||||
|
||||
/// <summary>
|
||||
/// 父节点
|
||||
/// </summary>
|
||||
public TreeNode Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户数据
|
||||
/// </summary>
|
||||
public object UserData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否展开
|
||||
/// </summary>
|
||||
public bool IsExpanded { get; set; } = false;
|
||||
|
||||
|
||||
public TreeNode(object userData)
|
||||
{
|
||||
UserData = userData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加子节点
|
||||
/// </summary>
|
||||
public void AddChild(TreeNode child)
|
||||
{
|
||||
child.Parent = this;
|
||||
Children.Add(child);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有子节点
|
||||
/// </summary>
|
||||
public void ClearChildren()
|
||||
{
|
||||
foreach(var child in Children)
|
||||
{
|
||||
child.Parent = null;
|
||||
}
|
||||
Children.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算节点的深度
|
||||
/// </summary>
|
||||
public int GetDepth()
|
||||
{
|
||||
int depth = 0;
|
||||
TreeNode current = this;
|
||||
while (current.Parent != null)
|
||||
{
|
||||
depth++;
|
||||
current = current.Parent;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 473cdc8e1dd7b0f43938ddb99287a2a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,152 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class TreeViewer : VisualElement
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<TreeViewer, UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
private readonly ListView _listView;
|
||||
private readonly List<TreeNode> _flattenList = new List<TreeNode>(1000);
|
||||
private readonly List<TreeNode> _rootList = new List<TreeNode>(100);
|
||||
|
||||
/// <summary>
|
||||
/// 制作列表元素
|
||||
/// </summary>
|
||||
public Action<VisualElement> makeItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 绑定列表数据
|
||||
/// </summary>
|
||||
public Action<VisualElement, object> bindItem { get; set; }
|
||||
|
||||
|
||||
public TreeViewer()
|
||||
{
|
||||
this.style.flexShrink = 1f;
|
||||
this.style.flexGrow = 1f;
|
||||
|
||||
// 创建ListView
|
||||
_listView = new ListView();
|
||||
_listView.style.flexShrink = 1f;
|
||||
_listView.style.flexGrow = 1f;
|
||||
_listView.itemsSource = _flattenList;
|
||||
_listView.makeItem = MakeItemInternal;
|
||||
_listView.bindItem = BindItemInternal;
|
||||
this.Add(_listView);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置根节点数据
|
||||
/// </summary>
|
||||
public void SetRootItem(TreeNode rootNode)
|
||||
{
|
||||
_rootList.Add(rootNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置根节点数据
|
||||
/// </summary>
|
||||
public void SetRootItems(List<TreeNode> rootNodes)
|
||||
{
|
||||
_rootList.AddRange(rootNodes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理数据
|
||||
/// </summary>
|
||||
public void ClearAll()
|
||||
{
|
||||
_rootList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新绘制视图
|
||||
/// </summary>
|
||||
public void RebuildView()
|
||||
{
|
||||
_flattenList.Clear();
|
||||
foreach (var treeRoot in _rootList)
|
||||
{
|
||||
FlattenTree(treeRoot, 0);
|
||||
}
|
||||
_listView.Rebuild();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将树形结构扁平化为列表
|
||||
/// </summary>
|
||||
private void FlattenTree(TreeNode node, int depth)
|
||||
{
|
||||
_flattenList.Add(node);
|
||||
if (node.IsExpanded)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
FlattenTree(child, depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VisualElement MakeItemInternal()
|
||||
{
|
||||
var container = new VisualElement();
|
||||
container.style.flexDirection = FlexDirection.Row;
|
||||
|
||||
// 折叠按钮
|
||||
var toggle = new ToggleFoldout();
|
||||
toggle.text = string.Empty;
|
||||
toggle.name = "foldout";
|
||||
toggle.style.alignSelf = Align.Center;
|
||||
toggle.style.width = 15;
|
||||
toggle.style.height = 15;
|
||||
toggle.RegisterValueChangedCallback((ChangeEvent<bool> callback) =>
|
||||
{
|
||||
var treeNode = toggle.userData as TreeNode;
|
||||
treeNode.IsExpanded = toggle.value;
|
||||
RebuildView();
|
||||
});
|
||||
container.Add(toggle);
|
||||
|
||||
// 用户自定义元素
|
||||
if (makeItem != null)
|
||||
{
|
||||
makeItem.Invoke(container);
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
private void BindItemInternal(VisualElement item, int index)
|
||||
{
|
||||
var treeNode = _flattenList[index];
|
||||
|
||||
// 设置折叠状态
|
||||
var toggle = item.Q<ToggleFoldout>("foldout");
|
||||
toggle.SetValueWithoutNotify(treeNode.IsExpanded);
|
||||
toggle.userData = treeNode;
|
||||
toggle.style.marginLeft = treeNode.GetDepth() * 15;
|
||||
|
||||
// 隐藏折叠按钮
|
||||
if (treeNode.Children.Count == 0)
|
||||
{
|
||||
toggle.style.visibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
// 用户自定义元素
|
||||
if (bindItem != null)
|
||||
{
|
||||
bindItem.Invoke(item, treeNode.UserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db2fb30e2d4512149b615fe6b2562ecd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,30 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public static class UIElementsCursor
|
||||
{
|
||||
private static PropertyInfo _defaultCursorId;
|
||||
private static PropertyInfo DefaultCursorId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_defaultCursorId != null)
|
||||
return _defaultCursorId;
|
||||
|
||||
_defaultCursorId = typeof(UnityEngine.UIElements.Cursor).GetProperty("defaultCursorId", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
return _defaultCursorId;
|
||||
}
|
||||
}
|
||||
|
||||
public static UnityEngine.UIElements.Cursor CreateCursor(MouseCursor cursorType)
|
||||
{
|
||||
var ret = (object)new UnityEngine.UIElements.Cursor();
|
||||
DefaultCursorId.SetValue(ret, (int)cursorType);
|
||||
return (UnityEngine.UIElements.Cursor)ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35d99a1727f773b46bc6a7bb1a2be970
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,39 +0,0 @@
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 分屏控件
|
||||
/// </summary>
|
||||
public class SplitView : TwoPaneSplitView
|
||||
{
|
||||
public new class UxmlFactory : UxmlFactory<SplitView, TwoPaneSplitView.UxmlTraits>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 窗口分屏适配
|
||||
/// </summary>
|
||||
public static void Adjuster(VisualElement root)
|
||||
{
|
||||
var topGroup = root.Q<VisualElement>("TopGroup");
|
||||
var bottomGroup = root.Q<VisualElement>("BottomGroup");
|
||||
topGroup.style.minHeight = 100f;
|
||||
bottomGroup.style.minHeight = 100f;
|
||||
root.Remove(topGroup);
|
||||
root.Remove(bottomGroup);
|
||||
var spliteView = new SplitView();
|
||||
spliteView.fixedPaneInitialDimension = 300;
|
||||
spliteView.orientation = TwoPaneSplitViewOrientation.Vertical;
|
||||
spliteView.contentContainer.Add(topGroup);
|
||||
spliteView.contentContainer.Add(bottomGroup);
|
||||
root.Add(spliteView);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,7 +1,6 @@
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
|
||||
#if UNITY_2019
|
||||
public static partial class UnityEngine_UIElements_ListView_Extension
|
||||
{
|
||||
@@ -21,5 +20,4 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 引擎图标名称
|
||||
/// </summary>
|
||||
public class UIElementsIcon
|
||||
{
|
||||
public const string RecordOn = "d_Record On@2x";
|
||||
public const string RecordOff = "d_Record Off@2x";
|
||||
|
||||
#if UNITY_2019
|
||||
public const string FoldoutOn = "IN foldout on";
|
||||
public const string FoldoutOff = "IN foldout";
|
||||
#else
|
||||
public const string FoldoutOn = "d_IN_foldout_on@2x";
|
||||
public const string FoldoutOff = "d_IN_foldout@2x";
|
||||
#endif
|
||||
|
||||
public const string VisibilityToggleOff = "animationvisibilitytoggleoff@2x";
|
||||
public const string VisibilityToggleOn = "animationvisibilitytoggleon@2x";
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41af337b41140c842b4b9f34a34f5cc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -8,6 +8,9 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public static class UIElementsTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置元素显隐
|
||||
/// </summary>
|
||||
public static void SetElementVisible(VisualElement element, bool visible)
|
||||
{
|
||||
if (element == null)
|
||||
@@ -16,6 +19,47 @@ namespace YooAsset.Editor
|
||||
element.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
element.style.visibility = visible ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置元素的文本最小宽度
|
||||
/// </summary>
|
||||
public static void SetElementLabelMinWidth(VisualElement element, int minWidth)
|
||||
{
|
||||
var label = element.Q<Label>();
|
||||
if (label != null)
|
||||
{
|
||||
// 设置最小宽度
|
||||
label.style.minWidth = minWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置按钮图标
|
||||
/// </summary>
|
||||
public static void SetToolbarButtonIcon(ToolbarButton element, string iconName)
|
||||
{
|
||||
var image = EditorGUIUtility.IconContent(iconName).image as Texture2D;
|
||||
element.style.backgroundImage = image;
|
||||
element.text = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 竖版分屏
|
||||
/// </summary>
|
||||
public static void SplitVerticalPanel(VisualElement root, VisualElement panelA, VisualElement panelB)
|
||||
{
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
root.Remove(panelA);
|
||||
root.Remove(panelB);
|
||||
|
||||
var spliteView = new TwoPaneSplitView();
|
||||
spliteView.fixedPaneInitialDimension = 300;
|
||||
spliteView.orientation = TwoPaneSplitViewOrientation.Vertical;
|
||||
spliteView.contentContainer.Add(panelA);
|
||||
spliteView.contentContainer.Add(panelB);
|
||||
root.Add(spliteView);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user