using System; using System.Collections.Generic; using System.Linq; using Jovian.EncounterSystem; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; namespace Jovian.EncounterSystem.Editor { /// Browser for every encounter across all tables. Search + kind filter + detail pane. Quest chains render as a tree rooted at the first step. public class EncounterBrowserWindow : EditorWindow { private const string AllKinds = "All"; private class Record { public EncounterTable table; public int index; public IEncounter encounter; } private readonly List allRecords = new(); private string searchText = string.Empty; private string kindFilter = AllKinds; private readonly Dictionary> issuesByEncounter = new(); private TreeView treeView; private VisualElement detailPane; private ToolbarMenu kindDropdown; [MenuItem("Jovian/Encounters/Encounter Browser")] public static void Open() { var window = GetWindow("Encounters"); window.minSize = new Vector2(640, 360); } private void CreateGUI() { BuildToolbar(); BuildSplit(); Refresh(); } private void BuildToolbar() { var toolbar = new Toolbar(); var search = new ToolbarSearchField(); search.style.flexGrow = 1f; search.RegisterValueChangedCallback(evt => { searchText = evt.newValue ?? string.Empty; ApplyFilter(); }); toolbar.Add(search); kindDropdown = new ToolbarMenu { text = $"Kind: {AllKinds}" }; foreach(var choice in GetKindChoices()) { var captured = choice; kindDropdown.menu.AppendAction(captured, _ => { kindFilter = captured; kindDropdown.text = $"Kind: {captured}"; ApplyFilter(); }); } toolbar.Add(kindDropdown); var refreshButton = new ToolbarButton(Refresh) { text = "Refresh" }; toolbar.Add(refreshButton); rootVisualElement.Add(toolbar); } private void BuildSplit() { var split = new TwoPaneSplitView(0, 280, TwoPaneSplitViewOrientation.Horizontal); split.style.flexGrow = 1f; rootVisualElement.Add(split); treeView = new TreeView { makeItem = MakeRow, bindItem = BindRow, fixedItemHeight = 22, selectionType = SelectionType.Single }; treeView.selectionChanged += OnSelectionChanged; treeView.style.flexGrow = 1f; split.Add(treeView); detailPane = new ScrollView(ScrollViewMode.Vertical) { style = { paddingLeft = 8, paddingTop = 8, paddingRight = 8, flexGrow = 1f } }; ShowEmptyDetail(); split.Add(detailPane); } private static VisualElement MakeRow() { var row = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, paddingLeft = 6, paddingRight = 6, height = 22 } }; var badge = new VisualElement { name = "issue-badge", style = { width = 8, height = 8, marginRight = 6, borderTopLeftRadius = 4, borderTopRightRadius = 4, borderBottomLeftRadius = 4, borderBottomRightRadius = 4, visibility = Visibility.Hidden } }; row.Add(badge); var label = new Label { name = "row-label", style = { flexGrow = 1f, unityTextAlign = TextAnchor.MiddleLeft } }; row.Add(label); return row; } private void BindRow(VisualElement element, int index) { var record = treeView.GetItemDataForIndex(index); var label = element.Q