using UnityEngine; using UnityEditor; using OctoCore.Localization; using System.IO; namespace Unheimlich.Editor { [CustomPropertyDrawer(typeof(OctoLocalizedTextData))] public class LocalizedTextFieldDrawer : PropertyDrawer { private const float LINE_HEIGHT = 20f; private const float SPACING = 2f; private const float LABEL_WIDTH = 80f; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { // Height for label + EN field + FR field return LINE_HEIGHT * 3 + SPACING * 2; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); OctoLocalizedTextData textData = property.objectReferenceValue as OctoLocalizedTextData; // If null, create new OctoLocalizedTextData if (textData == null) { textData = CreateLocalizedTextData(property); property.objectReferenceValue = textData; property.serializedObject.ApplyModifiedProperties(); } // Draw label Rect labelRect = new Rect(position.x, position.y, position.width, LINE_HEIGHT); EditorGUI.LabelField(labelRect, label, EditorStyles.boldLabel); // Draw EN field Rect enRect = new Rect(position.x, position.y + LINE_HEIGHT + SPACING, position.width, LINE_HEIGHT); DrawLanguageField(enRect, textData, OctoLanguages.English, "EN"); // Draw FR field Rect frRect = new Rect(position.x, position.y + (LINE_HEIGHT + SPACING) * 2, position.width, LINE_HEIGHT); DrawLanguageField(frRect, textData, OctoLanguages.French, "FR"); EditorGUI.EndProperty(); } private void DrawLanguageField(Rect position, OctoLocalizedTextData textData, OctoLanguages language, string labelText) { if (textData == null) return; // Ensure dictionary is initialized if (textData.Languages.Dictionary == null || textData.Languages.Dictionary.Count == 0) { #if UNITY_EDITOR textData.Init(); #endif } // Get language key string langKey = language.ToString(); // Get current value string currentValue = ""; if (textData.Languages.Dictionary.TryGetValue(langKey, out string value)) { currentValue = value; } // Draw label Rect labelRect = new Rect(position.x, position.y, LABEL_WIDTH, position.height); EditorGUI.LabelField(labelRect, labelText + ":"); // Draw text field Rect fieldRect = new Rect(position.x + LABEL_WIDTH, position.y, position.width - LABEL_WIDTH, position.height); EditorGUI.BeginChangeCheck(); string newValue = EditorGUI.TextField(fieldRect, currentValue); if (EditorGUI.EndChangeCheck()) { // Update via indexer (Dictionary is read-only property but supports indexer) textData.Languages.Dictionary[langKey] = newValue; EditorUtility.SetDirty(textData); AssetDatabase.SaveAssets(); } } private OctoLocalizedTextData CreateLocalizedTextData(SerializedProperty property) { // Get the object being edited Object targetObject = property.serializedObject.targetObject; string assetPath = AssetDatabase.GetAssetPath(targetObject); if (string.IsNullOrEmpty(assetPath)) return null; string directory = Path.GetDirectoryName(assetPath); string fileName = Path.GetFileNameWithoutExtension(assetPath); string propertyPath = property.propertyPath.Replace(".", "_"); // Create unique name string textDataName = $"text_{fileName}_{propertyPath}"; string textDataPath = $"{directory}/{textDataName}.asset"; // Check if already exists OctoLocalizedTextData existingData = AssetDatabase.LoadAssetAtPath(textDataPath); if (existingData != null) return existingData; // Create new OctoLocalizedTextData OctoLocalizedTextData newTextData = ScriptableObject.CreateInstance(); // Initialize via Init() method newTextData.Init(); // Save asset AssetDatabase.CreateAsset(newTextData, textDataPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); return newTextData; } } }