using Jovian.EncounterSystem; using UnityEditor; using UnityEngine; namespace Jovian.EncounterSystem.Editor { /// 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 float PreviewHeight = 32f; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { 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 idRect = new Rect(position.x, position.y, position.width, lineHeight); DrawIdPicker(idRect, library, idProp, label); var inlineRect = new Rect( position.x, position.y + lineHeight + spacing, position.width, lineHeight * 2); EditorGUI.PropertyField(inlineRect, inlineProp, new GUIContent("Inline")); var previewRect = new Rect( position.x, position.y + lineHeight + spacing + lineHeight * 2 + spacing, position.width, PreviewHeight); DrawPreview(previewRect, library, idProp, inlineProp); EditorGUI.EndProperty(); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { var lineHeight = EditorGUIUtility.singleLineHeight; var spacing = EditorGUIUtility.standardVerticalSpacing; // id + (inline 2 lines) + preview return lineHeight + spacing + lineHeight * 2 + spacing + PreviewHeight; } 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, label.text, 0, new[] { EmptyLibraryPlaceholder }); } return; } var count = library.lines.Count; var ids = new string[count + 1]; var names = new string[count + 1]; ids[0] = string.Empty; names[0] = NonePlaceholder; var currentIndex = 0; for(int i = 0; i < count; i++) { var line = library.lines[i]; var id = line?.id ?? string.Empty; ids[i + 1] = id; names[i + 1] = string.IsNullOrEmpty(id) ? $"" : id; if(id == idProp.stringValue && !string.IsNullOrEmpty(id)) { currentIndex = i + 1; } } var newIndex = EditorGUI.Popup(rect, label.text, currentIndex, names); if(newIndex != currentIndex) { idProp.stringValue = ids[newIndex]; } } private static void DrawPreview(Rect rect, DialogLineLibrary library, SerializedProperty idProp, SerializedProperty inlineProp) { var id = idProp.stringValue; var inline = inlineProp.stringValue; string resolved = null; if(library != null && !string.IsNullOrEmpty(id)) { resolved = library.Resolve(id); } if(string.IsNullOrEmpty(resolved)) { resolved = inline; } var style = new GUIStyle(EditorStyles.helpBox) { fontStyle = FontStyle.Italic, wordWrap = true }; var label = string.IsNullOrEmpty(resolved) ? "" : resolved; EditorGUI.LabelField(rect, new GUIContent("Preview: " + label), style); } } }