Browse Source

More work on GUI dictionary fields
Added string table inspector

BearishSun 10 years ago
parent
commit
ee3552b8d8

+ 1 - 1
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -37,7 +37,7 @@ namespace BansheeEngine
 	 */
 	enum class InspectorWindowIcon
 	{
-		Create, Clone, Clear, Resize, Delete, MoveUp, MoveDown
+		Create, Clone, Clear, Resize, Delete, MoveUp, MoveDown, Edit, Apply
 	};
 
 	/**

+ 4 - 0
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -1974,6 +1974,10 @@ namespace BansheeEngine
 			return getGUIIcon(L"InspectorMoveUpIcon.png");
 		case InspectorWindowIcon::MoveDown:
 			return getGUIIcon(L"InspectorMoveDownIcon.png");
+		case InspectorWindowIcon::Edit:
+			return getGUIIcon(L"InspectorEditIcon.png");
+		case InspectorWindowIcon::Apply:
+			return getGUIIcon(L"InspectorApplyIcon.png");
 		}
 
 		return HSpriteTexture();

+ 1 - 1
MBansheeEditor/EditorBuiltin.cs

@@ -33,7 +33,7 @@ namespace BansheeEditor
     /// </summary>
 	public enum InspectorWindowIcon  // Note: Must match C++ enum InspectorWindowIcon
 	{
-		Create, Clone, Clear, Resize, Delete, MoveUp, MoveDown
+		Create, Clone, Clear, Resize, Delete, MoveUp, MoveDown, Edit, Apply
 	};
 
     /// <summary>

+ 40 - 26
MBansheeEditor/GUI/GUIDictionaryField.cs

@@ -218,6 +218,16 @@ namespace BansheeEditor
         /// </summary>
         /// <param name="key">Key of the element to clone.</param>
         protected internal abstract void OnCloneButtonClicked(object key);
+
+        /// <summary>
+        /// Triggered when user clicks the edit or apply (depending on state) button next to the dictionary entry. Starts
+        /// edit mode for the element, if not already in edit mode. Applies edit mode changes if already in edit mode.
+        /// </summary>
+        /// <param name="key">Key of the element to edit.</param>
+        protected internal virtual void OnEditButtonClicked(object key)
+        {
+            // TODO
+        }
     }
 
     /// <summary>
@@ -232,18 +242,18 @@ namespace BansheeEditor
         /// Triggered when the reference array has been changed. This does not include changes that only happen to its 
         /// internal elements.
         /// </summary>
-        public Action<IDictionary> OnChanged;
+        public Action<Dictionary<Key, Value>> OnChanged;
 
         /// <summary>
         /// Triggered when an element in the list has been changed.
         /// </summary>
-        public Action OnValueChanged;
+        public Action<Key> OnValueChanged;
 
         /// <summary>
         /// Array object whose contents are displayed.
         /// </summary>
-        public IDictionary Dictionary { get { return dictionary; } }
-        protected IDictionary dictionary;
+        public Dictionary<Key, Value> Dictionary { get { return dictionary; } }
+        protected Dictionary<Key, Value> dictionary;
 
         /// <summary>
         /// Constructs a new empty dictionary GUI.
@@ -276,22 +286,22 @@ namespace BansheeEditor
         /// <inheritdoc/>
         protected internal override object GetValue(object key)
         {
-            return dictionary[key];
+            return dictionary[(Key)key];
         }
 
         /// <inheritdoc/>
         protected internal override void SetValue(object key, object value)
         {
-            dictionary[key] = value;
+            dictionary[(Key)key] = (Value)value;
 
             if (OnValueChanged != null)
-                OnValueChanged();
+                OnValueChanged((Key)key);
         }
 
         /// <inheritdoc/>
         protected internal override bool Contains(object key)
         {
-            return dictionary.Contains(key);;
+            return dictionary.ContainsKey((Key)key); ;
         }
 
         /// <inheritdoc/>
@@ -315,21 +325,16 @@ namespace BansheeEditor
         /// <inheritdoc/>
         protected internal override void OnDeleteButtonClicked(object key)
         {
-            dictionary.Remove(key);
+            dictionary.Remove((Key)key);
 
             if (OnValueChanged != null)
-                OnValueChanged();
+                OnValueChanged((Key)key);
         }
 
-        /// <summary>
-        /// Triggered when the user clicks on the clone button next to a dictionary entry. Clones the element and adds the 
-        /// clone to the dictionary. Non-value types must implement the <see cref="ICloneable"/> interface in order to be 
-        /// cloned. If it doesn't the clone will point to a null reference.
-        /// </summary>
-        /// <param name="key">Key of the element to clone.</param>
+        /// <inheritdoc/>
         protected internal override void OnCloneButtonClicked(object key)
         {
-            // TODO - Not supported
+            // TODO - Not implemented
 
             //int size = array.GetLength(0) + 1;
             //Array newArray = Array.CreateInstance(arrayType.GetElementType(), size);
@@ -376,7 +381,8 @@ namespace BansheeEditor
     /// </summary>
     public abstract class GUIDictionaryFieldRow
     {
-        private GUILayoutX rowLayout;
+        private GUILayoutY rowLayout;
+        private GUILayoutX keyRowLayout;
         private GUILayoutY keyLayout;
         private GUILayoutY valueLayout;
         private GUILayoutX titleLayout;
@@ -408,16 +414,19 @@ namespace BansheeEditor
             this.depth = depth;
 
             if (rowLayout == null)
-                rowLayout = parentLayout.AddLayoutX();
+                rowLayout = parentLayout.AddLayoutY();
+
+            if (keyRowLayout == null)
+                keyRowLayout = rowLayout.AddLayoutX();
 
             if (keyLayout == null)
-                keyLayout = rowLayout.AddLayoutY();
+                keyLayout = keyRowLayout.AddLayoutY();
 
             if (valueLayout == null)
                 valueLayout = rowLayout.AddLayoutY();
 
-            CreateKeyGUI(keyLayout);
-            GUILayoutX externalTitleLayout = CreateValueGUI(valueLayout);
+            GUILayoutX externalTitleLayout = CreateKeyGUI(keyLayout);
+            CreateValueGUI(valueLayout);
             if (localTitleLayout || (titleLayout != null && titleLayout == externalTitleLayout))
                 return;
 
@@ -428,7 +437,7 @@ namespace BansheeEditor
             }
             else
             {
-                GUILayoutY buttonCenter = rowLayout.AddLayoutY();
+                GUILayoutY buttonCenter = keyRowLayout.AddLayoutY();
                 buttonCenter.AddFlexibleSpace();
                 titleLayout = buttonCenter.AddLayoutX();
                 buttonCenter.AddFlexibleSpace();
@@ -438,29 +447,34 @@ namespace BansheeEditor
 
             GUIContent cloneIcon = new GUIContent(EditorBuiltin.GetInspectorWindowIcon(InspectorWindowIcon.Clone));
             GUIContent deleteIcon = new GUIContent(EditorBuiltin.GetInspectorWindowIcon(InspectorWindowIcon.Delete));
+            GUIContent editIcon = new GUIContent(EditorBuiltin.GetInspectorWindowIcon(InspectorWindowIcon.Edit));
 
             GUIButton cloneBtn = new GUIButton(cloneIcon, GUIOption.FixedWidth(30));
             GUIButton deleteBtn = new GUIButton(deleteIcon, GUIOption.FixedWidth(30));
+            GUIButton editBtn = new GUIButton(editIcon, GUIOption.FixedWidth(30));
 
             cloneBtn.OnClick += () => parent.OnCloneButtonClicked(key);
             deleteBtn.OnClick += () => parent.OnDeleteButtonClicked(key);
+            editBtn.OnClick += () => parent.OnEditButtonClicked(key);
 
             titleLayout.AddElement(cloneBtn);
             titleLayout.AddElement(deleteBtn);
+            titleLayout.AddSpace(10);
+            titleLayout.AddElement(editBtn);
         }
 
         /// <summary>
         /// Creates GUI elements specific to type in the key portion of a dictionary entry.
         /// </summary>
         /// <param name="layout">Layout to insert the row GUI elements to.</param>
-        protected abstract void CreateKeyGUI(GUILayoutY layout);
+        /// <returns>An optional title bar layout that the standard dictionary buttons will be appended to.</returns>
+        protected abstract GUILayoutX CreateKeyGUI(GUILayoutY layout);
 
         /// <summary>
         /// Creates GUI elements specific to type in the key portion of a dictionary entry.
         /// </summary>
         /// <param name="layout">Layout to insert the row GUI elements to.</param>
-        /// <returns>An optional title bar layout that the standard dictionary buttons will be appended to.</returns>
-        protected abstract GUILayoutX CreateValueGUI(GUILayoutY layout);
+        protected abstract void CreateValueGUI(GUILayoutY layout);
 
         /// <summary>
         /// Refreshes the GUI for the dictionary row and checks if anything was modified.

+ 1 - 1
MBansheeEditor/GUI/GUIEnumField.cs

@@ -113,7 +113,7 @@ namespace BansheeEditor
         ///                     default element style is used.</param>
         /// <param name="options">Options that allow you to control how is the element positioned and sized. This will 
         ///                       override any similar options set by style.</param>
-        public GUIEnumField(Type enumType, bool multiselect = false, string style = "", params GUIOption[] options)
+        public GUIEnumField(Type enumType, bool multiselect, string style = "", params GUIOption[] options)
         {
             Internal_CreateInstance(this, Enum.GetNames(enumType), Enum.GetValues(enumType), multiselect, 
                 null, 0, style, options, false);

+ 5 - 5
MBansheeEditor/GUI/GUIListField.cs

@@ -534,8 +534,8 @@ namespace BansheeEditor
         {
             list.RemoveAt(index);
 
-            if (OnValueChanged != null)
-                OnValueChanged();
+            if (OnChanged != null)
+                OnChanged(list);
         }
 
         /// <inheritdoc/>
@@ -546,9 +546,9 @@ namespace BansheeEditor
                 clonedEntry = SerializableUtility.Clone(list[index]);
 
             list.Add((ElementType)clonedEntry);
-            
-            if (OnValueChanged != null)
-                OnValueChanged();
+
+            if (OnChanged != null)
+                OnChanged(list);
         }
 
         /// <inheritdoc/>

+ 148 - 0
MBansheeEditor/Inspectors/StringTableInspector.cs

@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Renders an inspector for the <see cref="StringTable"/> resource.
+    /// </summary>
+    [CustomInspector(typeof(StringTable))]
+    internal class StringTableInspector : Inspector
+    {
+        private GUIEnumField languageField;
+        private GUIDictionaryField<string, string> valuesField = new GUIDictionaryField<string,string>();
+
+        private Dictionary<string, string> strings = new Dictionary<string,string>();
+
+        /// <inheritdoc/>
+        protected internal override void Initialize()
+        {
+            BuildGUI();
+        }
+
+        /// <inheritdoc/>
+        protected internal override bool Refresh()
+        {
+            bool anythingModified = false;
+
+            // Note: We're ignoring changes to the string table made externally here in order to avoid a lot of checks.
+            if ((Language) languageField.Value != StringTables.ActiveLanguage)
+            {
+                languageField.Value = (ulong)StringTables.ActiveLanguage;
+                anythingModified = true;
+                BuildGUI();
+            }
+
+            anythingModified |= valuesField.Refresh();
+
+            return anythingModified;
+        }
+
+        /// <summary>
+        /// Recreates all the GUI elements used by this inspector.
+        /// </summary>
+        private void BuildGUI()
+        {
+            layout.Clear();
+            strings.Clear();
+
+            StringTable stringTable = referencedObject as StringTable;
+            if(stringTable == null)
+                return;
+
+            string[] identifiers = stringTable.Identifiers;
+            foreach (var identifier in identifiers)
+                strings[identifier] = stringTable.GetString(identifier);
+
+            languageField = new GUIEnumField(typeof (Language));
+            languageField.OnSelectionChanged += x =>
+            {
+                StringTables.ActiveLanguage = (Language)x;
+                BuildGUI();
+                Refresh();
+            };
+
+            layout.AddElement(languageField);
+
+            valuesField.Update<StringTableEntry>(new LocEdString("Values"), strings, layout);
+
+            valuesField.OnChanged += x =>
+            {
+                foreach (var KVP in x)
+                {
+                    string oldValue;
+                    if (strings.TryGetValue(KVP.Key, out oldValue))
+                    {
+                        if (oldValue != KVP.Value)
+                            stringTable.SetString(KVP.Key, KVP.Value);
+                    }
+                    else
+                        stringTable.SetString(KVP.Key, KVP.Value);
+                }
+
+                foreach (var KVP in strings)
+                {
+                    if (!x.ContainsKey(KVP.Key))
+                        stringTable.RemoveString(KVP.Key);
+                }
+
+                BuildGUI();
+                Refresh();
+            };
+
+            valuesField.OnValueChanged += x =>
+            {
+                stringTable.SetString(x, strings[x]);
+            };
+            
+            layout.AddSpace(10);
+        }
+
+        /// <summary>
+        /// Row element used for displaying GUI for string table dictionary elements.
+        /// </summary>
+        public class StringTableEntry : GUIDictionaryFieldRow
+        {
+            private GUITextField keyField;
+            private GUITextField valueField;
+
+            /// <inheritdoc/>
+            protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
+            {
+                GUILayoutX titleLayout = layout.AddLayoutX();
+                keyField = new GUITextField(new LocEdString((string)key));
+                titleLayout.AddElement(keyField);
+
+                // TODO - Key changes are not being applied yet
+
+                return titleLayout;
+            }
+
+            /// <inheritdoc/>
+            protected override void CreateValueGUI(GUILayoutY layout)
+            {
+                string value = GetValue<string>();
+
+                valueField = new GUITextField(new LocEdString(value));
+                layout.AddElement(valueField);
+            }
+
+            /// <inheritdoc/>
+            internal protected override bool Refresh(out bool rebuildGUI)
+            {
+                rebuildGUI = false;
+
+                // Key cannot be changed so we don't check it here
+                string newValue = GetValue<string>();
+                if (valueField.Value != newValue)
+                {
+                    valueField.Value = newValue;
+                    return true;
+                }
+
+                return false;
+            }
+        }
+    }
+}

+ 5 - 5
MBansheeEngine/StringTables.cs

@@ -7,12 +7,12 @@ namespace BansheeEngine
     /// Manages string tables used for localizing text. Allows you to add and remove different tables and change the 
     /// active language.
     /// </summary>
-    public sealed class StringTables
+    public static class StringTables
     {
         /// <summary>
         /// Currently active language that determines the translations retrieved from localized strings.
         /// </summary>
-        public Language ActiveLanguage
+        public static Language ActiveLanguage
         {
             get
             {
@@ -31,7 +31,7 @@ namespace BansheeEngine
         /// </summary>
         /// <param name="id">Identifier of the string table.</param>
         /// <returns>String table with the specified identifier.</returns>
-        public StringTable GetTable(int id)
+        public static StringTable GetTable(int id)
         {
             return Internal_GetTable(id);
         }
@@ -41,7 +41,7 @@ namespace BansheeEngine
         /// </summary>
         /// <param name="id">Id of the string table to add/replace.</param>
         /// <param name="table">New string table to assign to the specified identifier.</param>
-        public void RegisterTable(int id, StringTable table)
+        public static void RegisterTable(int id, StringTable table)
         {
             Internal_SetTable(id, table);
         }
@@ -50,7 +50,7 @@ namespace BansheeEngine
         /// Removes the string table with the specified id.
         /// </summary>
         /// <param name="id">Identifier of the table to remove.</param>
-        public void UnregisterTable(int id)
+        public static void UnregisterTable(int id)
         {
             Internal_RemoveTable(id);
         }