using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using BaseGames.Enemies;
namespace BaseGames.Editor.Enemies
{
///
/// 敌人数据管理窗口(W-05)。
/// 技术:UI Toolkit TwoPaneSplitView + 手动标签页。
/// 菜单:BaseGames / Data / Enemy Data Manager
///
/// 左栏:可搜索的 EnemyStatsSO 列表 + [新建] 按钮。
/// 右栏两个标签页:
/// Stats — EnemyStatsSO 完整属性编辑
/// Loot — LootTableSO 浏览与编辑
///
public class EnemyDataWindow : EditorWindow
{
private static readonly StyleSheet _sharedUSS;
static EnemyDataWindow()
{
_sharedUSS = AssetDatabase.LoadAssetAtPath(
"Assets/_Game/Scripts/Editor/UIToolkit/Editor.uss");
}
[MenuItem("BaseGames/Data/Enemy Data Manager", priority = 102)]
public static void Open()
{
var wnd = GetWindow();
wnd.titleContent = new GUIContent("Enemy Data Manager");
wnd.minSize = new Vector2(720, 420);
}
// ── 状态 ─────────────────────────────────────────────────────────────
private List _enemies = new();
private List _filtered = new();
private List _lootTables = new();
private List _lootFiltered = new();
private ListView _enemyList;
private ListView _lootList;
private VisualElement _detailRoot; // Stats 标签页 Loot 详情区
private ScrollView _lootDetailRoot; // Loot 标签页 LootTable 详情区
private VisualElement _tabStats;
private VisualElement _tabLoot;
private Button _btnStats;
private Button _btnLoot;
private string _searchText = "";
private string _lootSearchText = "";
private int _activeTab = 0; // 0=Stats, 1=Loot
private InspectorElement _statsInspector;
private InspectorElement _lootInspector;
// ── 生命周期 ──────────────────────────────────────────────────────────
public void CreateGUI()
{
if (_sharedUSS != null)
rootVisualElement.styleSheets.Add(_sharedUSS);
// Toolbar
var toolbar = new Toolbar();
var searchField = new ToolbarSearchField { style = { flexGrow = 1 } };
searchField.RegisterValueChangedCallback(e => { _searchText = e.newValue; RefreshEnemyFilter(); });
searchField.tooltip = "按名称 / ID 过滤 EnemyStatsSO 列表";
toolbar.Add(searchField);
var btnCreate = new ToolbarButton(CreateNewEnemyStats) { text = "+ 新建敌人" };
var btnRefresh = new ToolbarButton(RefreshAll) { text = "↺" };
btnRefresh.tooltip = "重新扫描 Project 中的资产";
toolbar.Add(btnCreate);
toolbar.Add(btnRefresh);
rootVisualElement.Add(toolbar);
// Split view
var split = new TwoPaneSplitView(0, 230, TwoPaneSplitViewOrientation.Horizontal);
// ── 左栏:敌人列表 ────────────────────────────────────────────
var leftPane = new VisualElement { style = { minWidth = 150 } };
_enemyList = new ListView
{
selectionType = SelectionType.Single,
fixedItemHeight = 22,
makeItem = MakeEnemyItem,
bindItem = BindEnemyItem,
style = { flexGrow = 1 },
};
_enemyList.selectionChanged += OnEnemySelected;
leftPane.Add(_enemyList);
split.Add(leftPane);
// ── 右栏:标签页 + 内容 ───────────────────────────────────────
var rightPane = new VisualElement { style = { flexGrow = 1 } };
// 标签页按钮栏
var tabBar = new VisualElement();
tabBar.AddToClassList("tab-bar");
_btnStats = new Button(() => ActivateTab(0)) { text = "Stats" };
_btnLoot = new Button(() => ActivateTab(1)) { text = "Loot Table" };
_btnStats.AddToClassList("tab-button");
_btnLoot.AddToClassList("tab-button");
tabBar.Add(_btnStats);
tabBar.Add(_btnLoot);
rightPane.Add(tabBar);
// Stats 面板
_tabStats = new ScrollView { style = { flexGrow = 1 } };
_tabStats.AddToClassList("detail-panel");
rightPane.Add(_tabStats);
// Loot 面板(初始隐藏)
_tabLoot = BuildLootPanel();
_tabLoot.style.display = DisplayStyle.None;
rightPane.Add(_tabLoot);
split.Add(rightPane);
rootVisualElement.Add(split);
ActivateTab(0);
RefreshAll();
}
private void OnFocus() => RefreshAll();
// ── 标签页切换 ────────────────────────────────────────────────────────
private void ActivateTab(int tab)
{
_activeTab = tab;
_tabStats.style.display = tab == 0 ? DisplayStyle.Flex : DisplayStyle.None;
_tabLoot.style.display = tab == 1 ? DisplayStyle.Flex : DisplayStyle.None;
_btnStats.EnableInClassList("tab-button--active", tab == 0);
_btnLoot.EnableInClassList("tab-button--active", tab == 1);
}
// ── 敌人列表 ──────────────────────────────────────────────────────────
private void RefreshAll()
{
_enemies = EditorScaffoldUtils.FindAllAssetsOfType();
_enemies.Sort((a, b) => string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase));
_lootTables = EditorScaffoldUtils.FindAllAssetsOfType();
_lootTables.Sort((a, b) => string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase));
RefreshEnemyFilter();
RefreshLootFilter();
}
private void RefreshEnemyFilter()
{
_filtered = string.IsNullOrEmpty(_searchText)
? new List(_enemies)
: _enemies.Where(e => e != null &&
e.name.Contains(_searchText, StringComparison.OrdinalIgnoreCase)).ToList();
_enemyList.itemsSource = _filtered;
_enemyList.Rebuild();
}
private static VisualElement MakeEnemyItem()
{
var label = new Label();
label.AddToClassList("list-item");
return label;
}
private void BindEnemyItem(VisualElement element, int index)
{
var label = (Label)element;
var enemy = _filtered.Count > index ? _filtered[index] : null;
label.text = enemy != null ? enemy.name : "(null)";
}
private void OnEnemySelected(IEnumerable