diff --git a/Docs/Usage.md b/Docs/Usage.md index 1d82905..5970c1e 100644 --- a/Docs/Usage.md +++ b/Docs/Usage.md @@ -821,3 +821,17 @@ When enabled, the `RtlTextHandler` uses a smart token-based algorithm to: - Logical Input: `قیمت 500 تومان` - Rendered Output: `ناموت 500 تمیق` *(The Persian words are reshaped and placed in correct RTL flow, while the English numbers remain LTR)* + +### Generating TextMeshPro Fonts for Arabic/Persian + +To display Arabic and Persian texts correctly in TextMeshPro, you need to generate a Font Asset that includes all the necessary characters (Base letters, Presentation Forms, and Diacritics). + +We have provided a ready-to-use Unicode range file(s) at `Package/Assets`. + +**How to generate the font:** + +1. Open **Window > TextMeshPro > Font Asset Creator**. +2. Select your source TTF/OTF font (make sure it supports Arabic/Persian). +3. In the **Character Set** dropdown, choose **Custom Range**. +4. Open ranges file, copy its content, and paste it into the **Character Sequence (Hex)** box. +5. Generate the font atlas and save it. diff --git a/Package/Assets/ArabicAll.txt b/Package/Assets/ArabicAll.txt new file mode 100644 index 0000000..6268f18 --- /dev/null +++ b/Package/Assets/ArabicAll.txt @@ -0,0 +1 @@ +060C,061B,061F,0621,0622,0623,0624,0625,0626,0627,0628,0629,062A,062B,062C,062D,062E,062F,0630,0631,0632,0633,0634,0635,0636,0637,0638,0639,063A,0640,0641,0642,0643,0644,0645,0646,0647,0648,0649,064A,067E,0686,0698,06A9,06AF,06CC,FB56,FB57,FB58,FB59,FB7A,FB7B,FB7C,FB7D,FB8A,FB8B,FB8C,FB8D,FB92,FB93,FB94,FB95,FB8E,FB8F,FB90,FB91,FBFC-FBFF,FE70-FEFF,064b-065f,0670,FC5E-FC63,0660-0669,06F0-06F9 \ No newline at end of file diff --git a/Package/Assets/ArabicDigits.txt b/Package/Assets/ArabicDigits.txt new file mode 100644 index 0000000..2057924 --- /dev/null +++ b/Package/Assets/ArabicDigits.txt @@ -0,0 +1 @@ +0660-0669,06F0-06F9 \ No newline at end of file diff --git a/Package/Assets/ArabicLetters.txt b/Package/Assets/ArabicLetters.txt new file mode 100644 index 0000000..0f10c72 --- /dev/null +++ b/Package/Assets/ArabicLetters.txt @@ -0,0 +1 @@ +060C,061B,061F,0621,0622,0623,0624,0625,0626,0627,0628,0629,062A,062B,062C,062D,062E,062F,0630,0631,0632,0633,0634,0635,0636,0637,0638,0639,063A,0640,0641,0642,0643,0644,0645,0646,0647,0648,0649,064A,067E,0686,0698,06A9,06AF,06CC,FB56,FB57,FB58,FB59,FB7A,FB7B,FB7C,FB7D,FB8A,FB8B,FB8C,FB8D,FB92,FB93,FB94,FB95,FB8E,FB8F,FB90,FB91,FBFC-FBFF,FE70-FEFF \ No newline at end of file diff --git a/Package/Assets/ArabicTashkil.txt b/Package/Assets/ArabicTashkil.txt new file mode 100644 index 0000000..b26c29a --- /dev/null +++ b/Package/Assets/ArabicTashkil.txt @@ -0,0 +1 @@ +064b-065f,0670,FC5E-FC63 \ No newline at end of file diff --git a/Package/Assets/HebrewLetters.txt b/Package/Assets/HebrewLetters.txt new file mode 100644 index 0000000..715a28a --- /dev/null +++ b/Package/Assets/HebrewLetters.txt @@ -0,0 +1 @@ +0591-05C7,05D0-05EA,05EF-05F4 \ No newline at end of file diff --git a/Package/Core/LocalizationManager.cs b/Package/Core/LocalizationManager.cs index bb98705..e6b3690 100644 --- a/Package/Core/LocalizationManager.cs +++ b/Package/Core/LocalizationManager.cs @@ -213,9 +213,15 @@ public static void Initialize() #endif } +#if UNITY_EDITOR + string targetLanguage = !string.IsNullOrEmpty(_currentLanguageCode) && _availableLanguages.Contains(_currentLanguageCode) + ? _currentLanguageCode + : (!Application.isPlaying && _availableLanguages.Contains(DefaultLanguage) ? DefaultLanguage : DetectSystemLanguage()); +#else string targetLanguage = !string.IsNullOrEmpty(_currentLanguageCode) && _availableLanguages.Contains(_currentLanguageCode) ? _currentLanguageCode : DetectSystemLanguage(); +#endif SetLanguage(targetLanguage, useFallback: false); diff --git a/Package/Editor/Tabs/KeysTab.cs b/Package/Editor/Tabs/KeysTab.cs index 24f6f89..dd8c2c1 100644 --- a/Package/Editor/Tabs/KeysTab.cs +++ b/Package/Editor/Tabs/KeysTab.cs @@ -20,6 +20,7 @@ public sealed class KeysTab : LocalizationEditorTabBase private string _newKey = ""; private string _newValue = ""; private bool _pendingDelete; + private bool _isTranslating; private float _keysListViewportHeight; private static Texture2D _transparentTexture; @@ -478,8 +479,10 @@ private void DrawKeyActionButtons() if (GUILayout.Button("Rename", GUILayout.Width(65))) RenameKey(); - if (GUILayout.Button("Translate", GUILayout.Width(65))) - _ = _translationService.TranslateAndFill(Data.SelectedKey); + EditorGUI.BeginDisabledGroup(_isTranslating); + if (GUILayout.Button(_isTranslating ? "Translating..." : "Translate", GUILayout.Width(85))) + ExecuteTranslation(); + EditorGUI.EndDisabledGroup(); if (GUILayout.Button("Copy", GUILayout.Width(55))) ShowCopyKeyMenu(); @@ -546,6 +549,30 @@ private void ShowJsonOptionsMenu() menu.ShowAsContext(); } + private async void ExecuteTranslation() + { + if (_isTranslating || string.IsNullOrEmpty(Data.SelectedKey)) return; + + _isTranslating = true; + Editor.Repaint(); + + try + { + await _translationService.TranslateAndFill(Data.SelectedKey); + Editor.ShowNotification(new GUIContent("Translation completed successfully!")); + } + catch (Exception ex) + { + Debug.LogError($"Translation failed: {ex.Message}"); + Editor.ShowNotification(new GUIContent("Translation failed!")); + } + finally + { + _isTranslating = false; + Editor.Repaint(); + } + } + private void AddKey(bool isArray) { string cleanKey = _newKey?.Trim(); @@ -707,7 +734,7 @@ public override bool HandleKeyboardInput(Event evt) case KeyCode.T: if (ctrlPressed) { - _ = _translationService.TranslateAndFill(Data.SelectedKey); + ExecuteTranslation(); evt.Use(); return true; }