diff --git a/Editor/DialogLineRefDrawer.cs b/Editor/DialogLineRefDrawer.cs index 692aa09..c2736e0 100644 --- a/Editor/DialogLineRefDrawer.cs +++ b/Editor/DialogLineRefDrawer.cs @@ -3,50 +3,39 @@ using UnityEditor; using UnityEngine; namespace Jovian.EncounterSystem.Editor { - /// - /// Drawer for . Shows the library + id picker on one row, the inline - /// fallback text area underneath, and a resolved preview below that. Preserves WYSIWYG — the - /// final text is always visible. - /// + /// Id dropdown (library inherited from the owning asset's library field) + inline fallback + resolved preview. [CustomPropertyDrawer(typeof(DialogLineRef))] public class DialogLineRefDrawer : PropertyDrawer { private const string NonePlaceholder = ""; - private const string EmptyLibraryPlaceholder = ""; + private const string EmptyLibraryPlaceholder = ""; private const float PreviewHeight = 32f; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { - var libraryProp = property.FindPropertyRelative("library"); var idProp = property.FindPropertyRelative("id"); var inlineProp = property.FindPropertyRelative("inlineText"); + var library = ResolveLibrary(property); EditorGUI.BeginProperty(position, label, property); var lineHeight = EditorGUIUtility.singleLineHeight; var spacing = EditorGUIUtility.standardVerticalSpacing; - var libraryRect = new Rect(position.x, position.y, position.width, lineHeight); - EditorGUI.BeginChangeCheck(); - EditorGUI.PropertyField(libraryRect, libraryProp, label); - var libraryChanged = EditorGUI.EndChangeCheck(); + var idRect = new Rect(position.x, position.y, position.width, lineHeight); + DrawIdPicker(idRect, library, idProp, label); - using(new EditorGUI.IndentLevelScope()) { - var idRect = new Rect(position.x, position.y + lineHeight + spacing, position.width, lineHeight); - DrawIdPicker(idRect, libraryProp, idProp, libraryChanged); + var inlineRect = new Rect( + position.x, + position.y + lineHeight + spacing, + position.width, + lineHeight * 2); + EditorGUI.PropertyField(inlineRect, inlineProp, new GUIContent("Inline")); - var inlineRect = new Rect( - position.x, - position.y + (lineHeight + spacing) * 2, - position.width, - lineHeight * 2); - EditorGUI.PropertyField(inlineRect, inlineProp, new GUIContent("Inline")); - - var previewRect = new Rect( - position.x, - position.y + (lineHeight + spacing) * 2 + lineHeight * 2 + spacing, - position.width, - PreviewHeight); - DrawPreview(previewRect, libraryProp, idProp, inlineProp); - } + var previewRect = new Rect( + position.x, + position.y + lineHeight + spacing + lineHeight * 2 + spacing, + position.width, + PreviewHeight); + DrawPreview(previewRect, library, idProp, inlineProp); EditorGUI.EndProperty(); } @@ -54,18 +43,19 @@ namespace Jovian.EncounterSystem.Editor { public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { var lineHeight = EditorGUIUtility.singleLineHeight; var spacing = EditorGUIUtility.standardVerticalSpacing; - // library + id + (inline 2 lines) + preview - return (lineHeight + spacing) * 2 + lineHeight * 2 + spacing + PreviewHeight; + // id + (inline 2 lines) + preview + return lineHeight + spacing + lineHeight * 2 + spacing + PreviewHeight; } - private static void DrawIdPicker(Rect rect, SerializedProperty libraryProp, SerializedProperty idProp, bool libraryChanged) { - var library = libraryProp.objectReferenceValue as DialogLineLibrary; + private static DialogLineLibrary ResolveLibrary(SerializedProperty property) { + var libraryProp = property.serializedObject.FindProperty("library"); + return libraryProp?.objectReferenceValue as DialogLineLibrary; + } + + private static void DrawIdPicker(Rect rect, DialogLineLibrary library, SerializedProperty idProp, GUIContent label) { if(library == null || library.lines == null || library.lines.Count == 0) { using(new EditorGUI.DisabledScope(true)) { - EditorGUI.Popup(rect, "Id", 0, new[] { EmptyLibraryPlaceholder }); - } - if(libraryChanged) { - idProp.stringValue = string.Empty; + EditorGUI.Popup(rect, label.text, 0, new[] { EmptyLibraryPlaceholder }); } return; } @@ -82,24 +72,18 @@ namespace Jovian.EncounterSystem.Editor { var id = line?.id ?? string.Empty; ids[i + 1] = id; names[i + 1] = string.IsNullOrEmpty(id) ? $"" : id; - if(!libraryChanged && id == idProp.stringValue && !string.IsNullOrEmpty(id)) { + if(id == idProp.stringValue && !string.IsNullOrEmpty(id)) { currentIndex = i + 1; } } - if(libraryChanged) { - idProp.stringValue = string.Empty; - currentIndex = 0; - } - - var newIndex = EditorGUI.Popup(rect, "Id", currentIndex, names); + var newIndex = EditorGUI.Popup(rect, label.text, currentIndex, names); if(newIndex != currentIndex) { idProp.stringValue = ids[newIndex]; } } - private static void DrawPreview(Rect rect, SerializedProperty libraryProp, SerializedProperty idProp, SerializedProperty inlineProp) { - var library = libraryProp.objectReferenceValue as DialogLineLibrary; + private static void DrawPreview(Rect rect, DialogLineLibrary library, SerializedProperty idProp, SerializedProperty inlineProp) { var id = idProp.stringValue; var inline = inlineProp.stringValue; diff --git a/Editor/EncounterBrowserWindow.cs b/Editor/EncounterBrowserWindow.cs index 9deb9b9..3aea7ea 100644 --- a/Editor/EncounterBrowserWindow.cs +++ b/Editor/EncounterBrowserWindow.cs @@ -8,11 +8,7 @@ using UnityEngine; using UnityEngine.UIElements; namespace Jovian.EncounterSystem.Editor { - /// - /// Designer-facing browser for every authored across all - /// assets in the project. Virtualised ListView on the left, - /// property-field detail pane on the right. Search by id/name/description; filter by kind. - /// + /// 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"; @@ -23,13 +19,12 @@ namespace Jovian.EncounterSystem.Editor { } private readonly List allRecords = new(); - private List filteredRecords = new(); private string searchText = string.Empty; private string kindFilter = AllKinds; private readonly Dictionary> issuesByEncounter = new(); - private ListView listView; + private TreeView treeView; private VisualElement detailPane; private ToolbarMenu kindDropdown; @@ -78,15 +73,15 @@ namespace Jovian.EncounterSystem.Editor { split.style.flexGrow = 1f; rootVisualElement.Add(split); - listView = new ListView { + treeView = new TreeView { makeItem = MakeRow, bindItem = BindRow, fixedItemHeight = 22, selectionType = SelectionType.Single }; - listView.selectionChanged += OnSelectionChanged; - listView.style.flexGrow = 1f; - split.Add(listView); + treeView.selectionChanged += OnSelectionChanged; + treeView.style.flexGrow = 1f; + split.Add(treeView); detailPane = new ScrollView(ScrollViewMode.Vertical) { style = { paddingLeft = 8, paddingTop = 8, paddingRight = 8, flexGrow = 1f } @@ -134,7 +129,7 @@ namespace Jovian.EncounterSystem.Editor { } private void BindRow(VisualElement element, int index) { - var record = filteredRecords[index]; + var record = treeView.GetItemDataForIndex(index); var label = element.Q