From af34bafc5a2ec00703266df21c9c3df9bdea1973 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 22 Apr 2021 13:28:52 +0200 Subject: [PATCH] Improve LocalizedStringTable editor --- .../Assets/LocalizedStringTableWindow.cs | 116 +++++++++++++++++- Source/Engine/UI/GUI/Common/TextBoxBase.cs | 5 + Source/Engine/Utilities/Extensions.cs | 15 +++ 3 files changed, 133 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Windows/Assets/LocalizedStringTableWindow.cs b/Source/Editor/Windows/Assets/LocalizedStringTableWindow.cs index 7cd2472fb..ee48284db 100644 --- a/Source/Editor/Windows/Assets/LocalizedStringTableWindow.cs +++ b/Source/Editor/Windows/Assets/LocalizedStringTableWindow.cs @@ -1,11 +1,13 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. +using System; using System.Collections.Generic; using FlaxEditor.Content; using FlaxEditor.CustomEditors; using FlaxEditor.GUI; using FlaxEngine; using FlaxEngine.GUI; +using FlaxEngine.Utilities; namespace FlaxEditor.Windows.Assets { @@ -18,14 +20,101 @@ namespace FlaxEditor.Windows.Assets { private readonly CustomEditorPresenter _presenter; private readonly ToolStripButton _saveButton; + private readonly ToolStripButton _undoButton; + private readonly ToolStripButton _redoButton; + private readonly Undo _undo; private Proxy _proxy; + private class EntryEditor : CustomEditor + { + private TextBox[] _textBoxes; + private bool _isRefreshing; + + public override void Initialize(LayoutElementsContainer layout) + { + var values = (string[])Values[0]; + if (values == null || values.Length == 0) + { + values = new string[1]; + values[0] = string.Empty; + } + if (_textBoxes == null || _textBoxes.Length != values.Length) + _textBoxes = new TextBox[values.Length]; + for (int i = 0; i < values.Length; i++) + { + var value = values[i]; + var textBox = layout.TextBox(value.IsMultiline()); + textBox.TextBox.Tag = i; + textBox.TextBox.Text = value; + textBox.TextBox.TextBoxEditEnd += OnEditEnd; + _textBoxes[i] = textBox.TextBox; + } + } + + public override void Refresh() + { + base.Refresh(); + + var values = (string[])Values[0]; + if (values != null && values.Length == _textBoxes.Length) + { + _isRefreshing = true; + var style = FlaxEngine.GUI.Style.Current; + var wrongColor = new Color(1.0f, 0.0f, 0.02745f, 1.0f); + var wrongColorBorder = Color.Lerp(wrongColor, style.TextBoxBackground, 0.6f); + for (int i = 0; i < _textBoxes.Length; i++) + { + var textBox = _textBoxes[i]; + if (!textBox.IsEditing) + { + textBox.Text = values[i]; + if (string.IsNullOrEmpty(textBox.Text)) + { + textBox.BorderColor = wrongColorBorder; + textBox.BorderSelectedColor = wrongColor; + } + else + { + textBox.BorderColor = Color.Transparent; + textBox.BorderSelectedColor = style.BackgroundSelected; + } + } + } + _isRefreshing = false; + } + } + + protected override void Deinitialize() + { + base.Deinitialize(); + + _textBoxes = null; + _isRefreshing = false; + } + + private void OnEditEnd(TextBoxBase textBox) + { + if (_isRefreshing) + return; + var values = (string[])Values[0]; + var length = Mathf.Max(values?.Length ?? 0, 1); + var toSet = new string[length]; + if (values != null && values.Length == length) + Array.Copy(values, toSet, length); + var index = (int)textBox.Tag; + toSet[index] = textBox.Text; + SetValue(toSet); + } + } + private class Proxy { - [EditorOrder(0), Tooltip("The locale of the localized string table (eg. pl-PL).")] + [EditorOrder(0), EditorDisplay("General"), Tooltip("The locale of the localized string table (eg. pl-PL)."),] + [CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.CultureInfoEditor))] public string Locale; - [EditorOrder(10), Tooltip("The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.")] + [EditorOrder(10), EditorDisplay("Entries", EditorDisplayAttribute.InlineStyle), Tooltip("The string table. Maps the message id into the localized text. For plural messages the list contains separate items for value numbers.")] + [Collection(Spacing = 10, OverrideEditorTypeName = "FlaxEditor.Windows.Assets.LocalizedStringTableWindow+EntryEditor")] public Dictionary Entries; } @@ -33,8 +122,16 @@ namespace FlaxEditor.Windows.Assets public LocalizedStringTableWindow(Editor editor, AssetItem item) : base(editor, item) { + // Undo + _undo = new Undo(); + _undo.UndoDone += OnUndoRedo; + _undo.RedoDone += OnUndoRedo; + // Toolstrip _saveButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Save32, Save).LinkTooltip("Save"); + _toolstrip.AddSeparator(); + _undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo32, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)"); + _redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo32, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)"); // Panel var panel = new Panel(ScrollBars.Vertical) @@ -45,9 +142,19 @@ namespace FlaxEditor.Windows.Assets }; // Properties - _presenter = new CustomEditorPresenter(null, "Loading..."); + _presenter = new CustomEditorPresenter(_undo, "Loading..."); _presenter.Panel.Parent = panel; _presenter.Modified += MarkAsEdited; + + // Setup input actions + InputActions.Add(options => options.Undo, _undo.PerformUndo); + InputActions.Add(options => options.Redo, _undo.PerformRedo); + } + + private void OnUndoRedo(IUndoAction action) + { + MarkAsEdited(); + UpdateToolstrip(); } /// @@ -71,6 +178,8 @@ namespace FlaxEditor.Windows.Assets protected override void UpdateToolstrip() { _saveButton.Enabled = IsEdited; + _undoButton.Enabled = _undo.CanUndo; + _redoButton.Enabled = _undo.CanRedo; base.UpdateToolstrip(); } @@ -84,6 +193,7 @@ namespace FlaxEditor.Windows.Assets Entries = _asset.Entries, }; _presenter.Select(_proxy); + _undo.Clear(); ClearEditedFlag(); base.OnAssetLoaded(); diff --git a/Source/Engine/UI/GUI/Common/TextBoxBase.cs b/Source/Engine/UI/GUI/Common/TextBoxBase.cs index 2e4ef51e3..ae7990633 100644 --- a/Source/Engine/UI/GUI/Common/TextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/TextBoxBase.cs @@ -261,6 +261,11 @@ namespace FlaxEngine.GUI } } + /// + /// Gets a value indicating whether user is editing the text. + /// + public bool IsEditing => _isEditing; + /// /// Gets or sets text property. /// diff --git a/Source/Engine/Utilities/Extensions.cs b/Source/Engine/Utilities/Extensions.cs index 3eb31e1d2..0fc46efe7 100644 --- a/Source/Engine/Utilities/Extensions.cs +++ b/Source/Engine/Utilities/Extensions.cs @@ -44,6 +44,21 @@ namespace FlaxEngine.Utilities } } + /// + /// Checks if the text is multiline. + /// + /// Text to check. + /// True if text is a multiline, otherwise false. + public static bool IsMultiline(this string str) + { + for (int i = 0; i < str.Length; i++) + { + if (str[i] == '\n') + return true; + } + return false; + } + /// /// Splits string into lines ///