using Jovian.EncounterSystem; 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. /// [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 libraryProp = property.FindPropertyRelative("library"); var idProp = property.FindPropertyRelative("id"); var inlineProp = property.FindPropertyRelative("inlineText"); 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(); 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) * 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); } EditorGUI.EndProperty(); } 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; } private static void DrawIdPicker(Rect rect, SerializedProperty libraryProp, SerializedProperty idProp, bool libraryChanged) { var library = libraryProp.objectReferenceValue as DialogLineLibrary; 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; } 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(!libraryChanged && 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); 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; 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); } } }