AlicizaX/Client/Packages/com.alicizax.uxtool/Editor/UXGUI/SceneView/PrefabTab/PrefabSingleTab.cs

167 lines
6.2 KiB
C#
Raw Normal View History

2025-12-01 16:46:28 +08:00
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine.UIElements;
using System.IO;
using UnityEngine;
using System;
namespace AlicizaX.UXTool
2025-12-01 16:46:28 +08:00
{
public class PrefabSingleTab : VisualElement
{
public Button visual;
private string m_guid;
private static int m_maxwidth = PrefabTabs.m_maxWidth;
private static int m_minwidth = PrefabTabs.m_minWidth;
private static int m_maxcharacters = PrefabTabs.m_maxCharacters;
private static int m_mincharacters = PrefabTabs.m_minCharacters;
public PrefabSingleTab(FileInfo info, string guid, int prefabcounts, bool isclose, int width)
{
// 计算每个 tab 的推荐宽度(防空)
SceneView sceneView = SceneView.lastActiveSceneView;
int prewidth = 100;
if (sceneView != null && prefabcounts > 0)
{
prewidth = Mathf.Max(1, (int)sceneView.position.width / Math.Max(1, prefabcounts));
}
// 根 Button用于作为 tab 容器并响应 click
visual = new Button();
visual.name = "Tab";
// 基本样式(尽量还原 UXML 的样式)
visual.style.height = 20;
visual.style.flexDirection = FlexDirection.Row;
visual.style.alignItems = Align.Center;
visual.style.justifyContent = Justify.FlexStart;
visual.style.unityTextAlign = TextAnchor.MiddleCenter;
visual.style.backgroundColor = new StyleColor(new Color(60f / 255f, 60f / 255f, 60f / 255f, 1f));
// margin、padding、border 等默认即可
// Label
Label label = new Label();
label.name = "Label";
label.style.paddingLeft = 5;
label.style.whiteSpace = WhiteSpace.NoWrap;
label.style.unityTextAlign = TextAnchor.MiddleCenter;
label.style.alignSelf = Align.Center;
// label 默认宽度稍后设置为 nowwidth
// 关闭按钮
Button close = new Button();
close.name = "Close";
close.style.width = 20;
close.style.height = 20;
close.style.alignSelf = Align.Center;
close.style.marginLeft = 3;
close.style.marginRight = 3;
close.style.backgroundImage = new StyleBackground(EditorGUIUtility.IconContent("d_winbtn_mac_close_a").image as Texture2D);
close.style.backgroundSize = new BackgroundSize(new Length(80, LengthUnit.Percent), new Length(80, LengthUnit.Percent));
close.style.backgroundColor = Color.clear;
close.style.borderLeftWidth = 0;
close.style.borderRightWidth = 0;
visual.Add(label);
visual.Add(close);
int nowwidth = m_maxwidth;
if (isclose)
{
label.style.width = width;
nowwidth = width;
}
else
{
int computed = Math.Min(Math.Max(m_minwidth, prewidth), m_maxwidth);
label.style.width = computed;
nowwidth = computed;
}
int nowCharacterscounts = m_maxcharacters;
if (nowwidth < m_maxwidth)
nowCharacterscounts = Math.Max(m_maxcharacters - (int)((m_maxwidth - nowwidth) / 10), m_mincharacters);
m_guid = guid;
string fileName = Path.GetFileNameWithoutExtension(info.Name);
label.text = SetTextWithEllipsis(nowCharacterscounts, fileName);
// 事件绑定(与原逻辑一致)
close.clickable.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
close.clicked += OnClose;
close.RegisterCallback<MouseEnterEvent, VisualElement>(OnHoverClose, close);
close.RegisterCallback<MouseLeaveEvent, VisualElement>(OnHoverClose, close);
visual.RegisterCallback<MouseEnterEvent>(OnHoverChange);
visual.RegisterCallback<MouseLeaveEvent>(OnHoverChange);
visual.clickable.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse });
visual.clicked += OnClick;
visual.RegisterCallback<MouseDownEvent>(Callback);
// 将 visual 作为当前元素的一部分(方便外部访问 this.visual
this.Add(visual);
}
private void Callback(MouseDownEvent e)
{
if (e.button == 1)
{
ContextMenuUtils.Menu.BuildPrefabTabMenuItem(m_guid);
ContextMenuUtils.ShowContextMenu();
}
}
private void OnHoverChange(EventBase e)
{
if (m_guid == PrefabTabs.SelectedGuid) return;
if (e.eventTypeId == MouseEnterEvent.TypeId())
{
visual.style.backgroundColor = new StyleColor(new Color(78f / 255f, 78f / 255f, 78f / 255f, 1f));
}
else if (e.eventTypeId == MouseLeaveEvent.TypeId())
{
visual.style.backgroundColor = new StyleColor(new Color(60f / 255f, 60f / 255f, 60f / 255f, 1f));
}
}
private void OnHoverClose(EventBase e, VisualElement close)
{
// if (e.eventTypeId == MouseEnterEvent.TypeId())
// {
// close.style.backgroundColor = new StyleColor(new Color(60f / 255f, 60f / 255f, 60f / 255f, 1f));
// }
// else if (e.eventTypeId == MouseLeaveEvent.TypeId())
// {
// close.style.backgroundColor = new StyleColor(new Color(60f / 255f, 60f / 255f, 60f / 255f, 0f));
// }
}
private void OnClick()
{
PrefabTabs.OpenTab(m_guid, true);
}
private void OnClose()
{
PrefabTabs.CloseTab(m_guid);
}
private string SetTextWithEllipsis(int count, string name)
{
if (name.Length <= count)
{
return name;
}
else
{
string ans = name.Substring(0, Math.Max(0, count - 3));
ans += "...";
return ans;
}
}
}
}
#endif