Jelajahi Sumber

GUI dictionary:
- Rows no longer depend on keys
- Optional sort method can be specified by the user

BearishSun 10 tahun lalu
induk
melakukan
bebb59cb6b

+ 157 - 92
MBansheeEditor/GUI/GUIDictionaryField.cs

@@ -13,7 +13,7 @@ namespace BansheeEditor
     {
     {
         private const int IndentAmount = 5;
         private const int IndentAmount = 5;
 
 
-        protected List<GUIDictionaryFieldRow> rows = new List<GUIDictionaryFieldRow>();
+        protected Dictionary<int, GUIDictionaryFieldRow> rows = new Dictionary<int, GUIDictionaryFieldRow>();
         protected GUIDictionaryFieldRow editRow;
         protected GUIDictionaryFieldRow editRow;
         protected GUILayoutX guiChildLayout;
         protected GUILayoutX guiChildLayout;
         protected GUILayoutX guiTitleLayout;
         protected GUILayoutX guiTitleLayout;
@@ -21,6 +21,7 @@ namespace BansheeEditor
         protected bool isExpanded;
         protected bool isExpanded;
         protected int depth;
         protected int depth;
 
 
+        private int editRowIdx = -1;
         private object editKey;
         private object editKey;
         private object editValue;
         private object editValue;
         private object editOriginalKey;
         private object editOriginalKey;
@@ -112,7 +113,7 @@ namespace BansheeEditor
                         GUIDictionaryFieldRow newRow = new T();
                         GUIDictionaryFieldRow newRow = new T();
                         newRow.BuildGUI(this, guiContentLayout, i, depth);
                         newRow.BuildGUI(this, guiContentLayout, i, depth);
 
 
-                        rows.Add(newRow);
+                        rows.Add(i, newRow);
                     }
                     }
 
 
                     editRow = new T();
                     editRow = new T();
@@ -186,37 +187,70 @@ namespace BansheeEditor
             editRow.Destroy();
             editRow.Destroy();
         }
         }
 
 
+        /// <summary>
+        /// Checks is the specified row index the temporary edit row.
+        /// </summary>
+        /// <param name="rowIdx">Sequential index of the row to check.</param>
+        /// <returns>True if the index is of an edit row.</returns>
+        private bool IsTemporaryRow(int rowIdx)
+        {
+            return rowIdx == rows.Count;
+        }
+
         /// <summary>
         /// <summary>
         /// Gets a value of an element at the specified index in the list. Also handles temporary edit fields.
         /// Gets a value of an element at the specified index in the list. Also handles temporary edit fields.
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the element whose value to retrieve.</param>
+        /// <param name="rowIdx">Sequential index of the row to set the value for.</param>
         /// <returns>Value of the list element at the specified key.</returns>
         /// <returns>Value of the list element at the specified key.</returns>
-        protected internal virtual object GetValueInternal(object key)
+        protected internal virtual object GetValueInternal(int rowIdx)
         {
         {
-            if (key == editKey)
+            if (rowIdx == editRowIdx)
                 return editValue;
                 return editValue;
-
-            return GetValue(key);
+            else
+                return GetValue(GetKey(rowIdx));
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Sets a value of an element at the specified index in the list. Also handles temporary edit fields.
         /// Sets a value of an element at the specified index in the list. Also handles temporary edit fields.
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the element whose value to set.</param>
+        /// <param name="rowIdx">Sequential index of the row to set the value for.</param>
         /// <param name="value">Value to assign to the element. Caller must ensure it is of valid type.</param>
         /// <param name="value">Value to assign to the element. Caller must ensure it is of valid type.</param>
-        protected internal virtual void SetValueInternal(object key, object value)
+        protected internal virtual void SetValueInternal(int rowIdx, object value)
         {
         {
-            if (key == editKey)
+            if (rowIdx == editRowIdx)
                 editValue = value;
                 editValue = value;
+            else
+                SetValue(GetKey(rowIdx), value);
+        }
 
 
-            SetValue(key, value);
+        /// <summary>
+        /// Changes the value of the key of the specified row.
+        /// </summary>
+        /// <param name="rowIdx">Sequential index of the row to set the key for.</param>
+        /// <param name="key">Key to assign to the specified row.</param>
+        protected internal void SetKey(int rowIdx, object key)
+        {
+            if (editRowIdx != rowIdx)
+            {
+                Debug.LogError("Cannot change a dictionary row that is not in edit state.");
+                return;
+            }
+
+            editKey = key;
         }
         }
 
 
+        /// <summary>
+        /// Gets a key for a row at the specified index.
+        /// </summary>
+        /// <param name="rowIdx">Sequential index of the row for which to retrieve the key.</param>
+        /// <returns>Key for a row at the specified index..</returns>
+        protected internal abstract object GetKey(int rowIdx);
+
         /// <summary>
         /// <summary>
         /// Gets a value of an element at the specified index in the list.
         /// Gets a value of an element at the specified index in the list.
         /// </summary>
         /// </summary>
         /// <param name="key">Key of the element whose value to retrieve.</param>
         /// <param name="key">Key of the element whose value to retrieve.</param>
-        /// <returns>Value of the list element at the specified key.</returns>
+        /// <returns>Value of the dictionary entry for the specified key.</returns>
         protected internal abstract object GetValue(object key);
         protected internal abstract object GetValue(object key);
 
 
         /// <summary>
         /// <summary>
@@ -281,7 +315,7 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         protected virtual void OnAddButtonClicked()
         protected virtual void OnAddButtonClicked()
         {
         {
-            if (editKey != null)
+            if (editRowIdx != -1)
             {
             {
                 DialogBox.Open(
                 DialogBox.Open(
                     new LocEdString("Edit in progress."),
                     new LocEdString("Edit in progress."),
@@ -316,23 +350,23 @@ namespace BansheeEditor
         /// Triggered when the user clicks on the delete button next to a dictionary entry. Deletes an element in the 
         /// Triggered when the user clicks on the delete button next to a dictionary entry. Deletes an element in the 
         /// dictionary. 
         /// dictionary. 
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the element to remove.</param>
-        protected internal virtual void OnDeleteButtonClicked(object key)
+        /// <param name="rowIdx">Sequential row index of the entry that was clicked.</param>
+        protected internal virtual void OnDeleteButtonClicked(int rowIdx)
         {
         {
-            if (editKey != null)
+            if (editRowIdx != -1)
                 DiscardChanges();
                 DiscardChanges();
             else
             else
-                RemoveEntry(key);
+                RemoveEntry(GetKey(rowIdx));
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Triggered when the user clicks on the clone button next to a dictionary entry. Clones an element and
         /// Triggered when the user clicks on the clone button next to a dictionary entry. Clones an element and
         /// adds the clone to the dictionary.
         /// adds the clone to the dictionary.
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the element to clone.</param>
-        protected internal virtual void OnCloneButtonClicked(object key)
+        /// <param name="rowIdx">Sequential row index of the entry that was clicked.</param>
+        protected internal virtual void OnCloneButtonClicked(int rowIdx)
         {
         {
-            if (editKey != null)
+            if (editRowIdx != -1)
             {
             {
                 DialogBox.Open(
                 DialogBox.Open(
                     new LocEdString("Edit in progress."),
                     new LocEdString("Edit in progress."),
@@ -345,31 +379,31 @@ namespace BansheeEditor
                         {
                         {
                             case DialogBox.ResultType.Yes:
                             case DialogBox.ResultType.Yes:
                                 if (ApplyChanges())
                                 if (ApplyChanges())
-                                    StartClone(key);
+                                    StartClone(rowIdx);
                                 break;
                                 break;
                             case DialogBox.ResultType.No:
                             case DialogBox.ResultType.No:
                                 DiscardChanges();
                                 DiscardChanges();
-                                StartClone(key);
+                                StartClone(rowIdx);
                                 break;
                                 break;
                         }
                         }
                     });
                     });
             }
             }
             else
             else
-                StartClone(key);
+                StartClone(rowIdx);
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Triggered when user clicks the edit or apply (depending on state) button next to the dictionary entry. Starts
         /// 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.
         /// edit mode for the element, if not already in edit mode. Applies edit mode changes if already in edit mode.
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the element to edit.</param>
-        protected internal virtual void OnEditButtonClicked(object key)
+        /// <param name="rowIdx">Sequential row index of the entry that was clicked.</param>
+        protected internal virtual void OnEditButtonClicked(int rowIdx)
         {
         {
-            if (editKey == key)
+            if (editRowIdx == rowIdx)
                 ApplyChanges();
                 ApplyChanges();
             else
             else
             {
             {
-                if (editKey != null)
+                if (editRowIdx != -1)
                 {
                 {
                     DialogBox.Open(
                     DialogBox.Open(
                         new LocEdString("Edit in progress."),
                         new LocEdString("Edit in progress."),
@@ -382,49 +416,35 @@ namespace BansheeEditor
                             {
                             {
                                 case DialogBox.ResultType.Yes:
                                 case DialogBox.ResultType.Yes:
                                     if (ApplyChanges())
                                     if (ApplyChanges())
-                                        StartEdit(key);
+                                        StartEdit(rowIdx);
                                     break;
                                     break;
                                 case DialogBox.ResultType.No:
                                 case DialogBox.ResultType.No:
                                     DiscardChanges();
                                     DiscardChanges();
-                                    StartEdit(key);
+                                    StartEdit(rowIdx);
                                     break;
                                     break;
                             }
                             }
                         });
                         });
                 }
                 }
                 else
                 else
-                    StartEdit(key);
+                    StartEdit(rowIdx);
             }
             }
         }
         }
 
 
-        /// <summary>
-        /// Returns a row that displays contents of the entry under the specified key.
-        /// </summary>
-        /// <param name="key">Key of the row to retrieve.</param>
-        /// <returns>GUI representation of the row under the specified key if found, null otherwise.</returns>
-        private GUIDictionaryFieldRow GetRow(object key)
-        {
-            for (int i = 0; i < rows.Count; i++)
-            {
-                if (rows[i].Key == key)
-                    return rows[i];
-            }
-
-            return null;
-        }
-
         /// <summary>
         /// <summary>
         /// Starts an edit operation on a row with the specified key. Allows the user to change the key of the specified row.
         /// Starts an edit operation on a row with the specified key. Allows the user to change the key of the specified row.
         /// Caller must ensure no edit operation is already in progress.
         /// Caller must ensure no edit operation is already in progress.
         /// </summary>
         /// </summary>
-        /// <param name="key">Key of the row to start the edit operation on.</param>
-        private void StartEdit(object key)
+        /// <param name="rowIdx">Sequential row index of the entry to edit.</param>
+        private void StartEdit(int rowIdx)
         {
         {
+            object key = GetKey(rowIdx);
+
             editKey = SerializableUtility.Clone(key);
             editKey = SerializableUtility.Clone(key);
             editValue = SerializableUtility.Clone(GetValue(key));
             editValue = SerializableUtility.Clone(GetValue(key));
             editOriginalKey = key;
             editOriginalKey = key;
+            editRowIdx = rowIdx;
 
 
-            GUIDictionaryFieldRow row = GetRow(key);
-            row.EditMode = true;
+            rows[rowIdx].EditMode = true;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -436,8 +456,8 @@ namespace BansheeEditor
             editKey = CreateKey();
             editKey = CreateKey();
             editValue = CreateValue();
             editValue = CreateValue();
             editOriginalKey = null;
             editOriginalKey = null;
+            editRowIdx = rows.Count;
 
 
-            editRow.Key = editKey;
             editRow.Enabled = true;
             editRow.Enabled = true;
             editRow.EditMode = true;
             editRow.EditMode = true;
         }
         }
@@ -453,8 +473,8 @@ namespace BansheeEditor
             editKey = SerializableUtility.Clone(key);
             editKey = SerializableUtility.Clone(key);
             editValue = SerializableUtility.Clone(GetValue(key));
             editValue = SerializableUtility.Clone(GetValue(key));
             editOriginalKey = null;
             editOriginalKey = null;
+            editRowIdx = rows.Count;
 
 
-            editRow.Key = editKey;
             editRow.Enabled = true;
             editRow.Enabled = true;
             editRow.EditMode = true;
             editRow.EditMode = true;
         }
         }
@@ -466,7 +486,7 @@ namespace BansheeEditor
         ///          </returns>
         ///          </returns>
         private bool ApplyChanges()
         private bool ApplyChanges()
         {
         {
-            if (editKey == null)
+            if (editRowIdx == -1)
                 return true;
                 return true;
 
 
             if (Contains(editKey))
             if (Contains(editKey))
@@ -481,22 +501,23 @@ namespace BansheeEditor
             else
             else
             {
             {
                 if (editOriginalKey != null)
                 if (editOriginalKey != null)
-                {
                     RemoveEntry(editOriginalKey);
                     RemoveEntry(editOriginalKey);
 
 
-                    GUIDictionaryFieldRow row = GetRow(editOriginalKey);
-                    row.EditMode = false;
-                }
-                else // No original key means its a new element which uses the temporary edit row
+                if (IsTemporaryRow(editRowIdx))
                 {
                 {
                     editRow.EditMode = false;
                     editRow.EditMode = false;
                     editRow.Enabled = false;
                     editRow.Enabled = false;
                 }
                 }
+                else
+                {
+                    rows[editRowIdx].EditMode = false;
+                }
 
 
                 AddEntry(editKey, editValue);
                 AddEntry(editKey, editValue);
                 editKey = null;
                 editKey = null;
                 editValue = null;
                 editValue = null;
                 editOriginalKey = null;
                 editOriginalKey = null;
+                editRowIdx = -1;
 
 
                 return true;
                 return true;
             }
             }
@@ -507,11 +528,13 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         private void DiscardChanges()
         private void DiscardChanges()
         {
         {
-            if (editKey != null)
+            if (editRowIdx != -1)
             {
             {
                 editKey = null;
                 editKey = null;
                 editValue = null;
                 editValue = null;
+                editOriginalKey = null;
                 editRow.Enabled = false;
                 editRow.Enabled = false;
+                editRowIdx = -1;
             }
             }
         }
         }
     }
     }
@@ -522,8 +545,10 @@ namespace BansheeEditor
     /// </summary>
     /// </summary>
     /// <typeparam name="Key">Type of key used by the dictionary.</typeparam>
     /// <typeparam name="Key">Type of key used by the dictionary.</typeparam>
     /// <typeparam name="Value">Type of value stored in the dictionary.</typeparam>
     /// <typeparam name="Value">Type of value stored in the dictionary.</typeparam>
-    public class GUIDictionaryField<Key, Value> : GUIDictionaryFieldBase 
+    public class GUIDictionaryField<Key, Value> : GUIDictionaryFieldBase
     {
     {
+        public delegate int SortDictionaryDelegate(Key a, Key b);
+
         /// <summary>
         /// <summary>
         /// Triggered when the reference array has been changed. This does not include changes that only happen to its 
         /// Triggered when the reference array has been changed. This does not include changes that only happen to its 
         /// internal elements.
         /// internal elements.
@@ -535,12 +560,19 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         public Action<Key> OnValueChanged;
         public Action<Key> OnValueChanged;
 
 
+        /// <summary>
+        /// Optional method that will be used for sorting the elements in the dictionary.
+        /// </summary>
+        public SortDictionaryDelegate SortMethod;
+
         /// <summary>
         /// <summary>
         /// Array object whose contents are displayed.
         /// Array object whose contents are displayed.
         /// </summary>
         /// </summary>
         public Dictionary<Key, Value> Dictionary { get { return dictionary; } }
         public Dictionary<Key, Value> Dictionary { get { return dictionary; } }
         protected Dictionary<Key, Value> dictionary;
         protected Dictionary<Key, Value> dictionary;
 
 
+        private List<Key> orderedKeys = new List<Key>();
+
         /// <summary>
         /// <summary>
         /// Constructs a new empty dictionary GUI.
         /// Constructs a new empty dictionary GUI.
         /// </summary>
         /// </summary>
@@ -567,6 +599,34 @@ namespace BansheeEditor
                 base.Update<RowType>(title, false, dictionary.Count, layout, depth);
                 base.Update<RowType>(title, false, dictionary.Count, layout, depth);
             else
             else
                 base.Update<RowType>(title, true, 0, layout, depth);
                 base.Update<RowType>(title, true, 0, layout, depth);
+
+            UpdateKeys();
+        }
+
+        /// <summary>
+        /// Updates the ordered set of keys used for mapping sequential indexes to keys. Should be called whenever a 
+        /// dictionary key changes.
+        /// </summary>
+        private void UpdateKeys()
+        {
+            orderedKeys.Clear();
+
+            if (dictionary != null)
+            {
+                foreach (var KVP in dictionary)
+                    orderedKeys.Add(KVP.Key);
+
+                if (SortMethod != null)
+                    orderedKeys.Sort((x,y) => SortMethod(x, y));
+                else
+                    orderedKeys.Sort();
+            }
+        }
+
+        /// <inheritdoc/>
+        protected internal override object GetKey(int rowIdx)
+        {
+            return orderedKeys[rowIdx];
         }
         }
 
 
         /// <inheritdoc/>
         /// <inheritdoc/>
@@ -597,6 +657,8 @@ namespace BansheeEditor
 
 
             if (OnChanged != null)
             if (OnChanged != null)
                 OnChanged(dictionary);
                 OnChanged(dictionary);
+
+            UpdateKeys();
         }
         }
 
 
         /// <inheritdoc/>
         /// <inheritdoc/>
@@ -606,6 +668,8 @@ namespace BansheeEditor
 
 
             if (OnChanged != null)
             if (OnChanged != null)
                 OnChanged(dictionary);
                 OnChanged(dictionary);
+
+            UpdateKeys();
         }
         }
 
 
         /// <inheritdoc/>
         /// <inheritdoc/>
@@ -627,6 +691,8 @@ namespace BansheeEditor
 
 
             if (OnChanged != null)
             if (OnChanged != null)
                 OnChanged(dictionary);
                 OnChanged(dictionary);
+
+            UpdateKeys();
         }
         }
 
 
         /// <inheritdoc/>
         /// <inheritdoc/>
@@ -636,6 +702,8 @@ namespace BansheeEditor
 
 
             if (OnChanged != null)
             if (OnChanged != null)
                 OnChanged(dictionary);
                 OnChanged(dictionary);
+
+            UpdateKeys();
         }
         }
     }
     }
 
 
@@ -655,32 +723,9 @@ namespace BansheeEditor
         private bool enabled = true;
         private bool enabled = true;
         private GUIDictionaryFieldBase parent;
         private GUIDictionaryFieldBase parent;
 
 
-        protected object key;
+        protected int rowIdx;
         protected int depth;
         protected int depth;
 
 
-        /// <summary>
-        /// Key of the dictionary entry displayed by this row GUI.
-        /// </summary>
-        internal object Key
-        {
-            get { return key; }
-            set
-            {
-                if(rowLayout != null)
-                {
-                    rowLayout.Clear();
-                    rowLayout = null;
-                    keyRowLayout = null;
-                    keyLayout = null;
-                    valueLayout = null;
-                    titleLayout = null;
-                    localTitleLayout = false;
-                }
-
-                BuildGUI(parent, null, value, depth);
-            }
-        }
-
         /// <summary>
         /// <summary>
         /// Determines is the row currently being displayed.
         /// Determines is the row currently being displayed.
         /// </summary>
         /// </summary>
@@ -729,12 +774,12 @@ namespace BansheeEditor
         /// </summary>
         /// </summary>
         /// <param name="parent">Parent array GUI object that the entry is contained in.</param>
         /// <param name="parent">Parent array GUI object that the entry is contained in.</param>
         /// <param name="parentLayout">Parent layout that row GUI elements will be added to.</param>
         /// <param name="parentLayout">Parent layout that row GUI elements will be added to.</param>
-        /// <param name="key">Key of the element to create GUI for.</param>
+        /// <param name="rowIdx">Sequential index of the row.</param>
         /// <param name="depth">Determines the depth at which the element is rendered.</param>
         /// <param name="depth">Determines the depth at which the element is rendered.</param>
-        internal void BuildGUI(GUIDictionaryFieldBase parent, GUILayout parentLayout, object key, int depth)
+        internal void BuildGUI(GUIDictionaryFieldBase parent, GUILayout parentLayout, int rowIdx, int depth)
         {
         {
             this.parent = parent;
             this.parent = parent;
-            this.key = key;
+            this.rowIdx = rowIdx;
             this.depth = depth;
             this.depth = depth;
 
 
             if (rowLayout == null)
             if (rowLayout == null)
@@ -777,9 +822,9 @@ namespace BansheeEditor
             deleteBtn = new GUIButton(deleteIcon, GUIOption.FixedWidth(30));
             deleteBtn = new GUIButton(deleteIcon, GUIOption.FixedWidth(30));
             editBtn = new GUIButton(editIcon, GUIOption.FixedWidth(30));
             editBtn = new GUIButton(editIcon, GUIOption.FixedWidth(30));
 
 
-            cloneBtn.OnClick += () => parent.OnCloneButtonClicked(key);
-            deleteBtn.OnClick += () => parent.OnDeleteButtonClicked(key);
-            editBtn.OnClick += () => parent.OnEditButtonClicked(key);
+            cloneBtn.OnClick += () => parent.OnCloneButtonClicked(rowIdx);
+            deleteBtn.OnClick += () => parent.OnDeleteButtonClicked(rowIdx);
+            editBtn.OnClick += () => parent.OnEditButtonClicked(rowIdx);
 
 
             titleLayout.AddElement(cloneBtn);
             titleLayout.AddElement(cloneBtn);
             titleLayout.AddElement(deleteBtn);
             titleLayout.AddElement(deleteBtn);
@@ -811,6 +856,26 @@ namespace BansheeEditor
             return false;
             return false;
         }
         }
 
 
+        /// <summary>
+        /// Gets the key contained in this dictionary's row.
+        /// </summary>
+        /// <typeparam name="T">Type of the key. Must match the dictionary's element type.</typeparam>
+        /// <returns>Key in this dictionary's row.</returns>
+        protected T GetKey<T>()
+        {
+            return (T)parent.GetKey(rowIdx);
+        }
+
+        /// <summary>
+        /// Sets the key for in this dictionary's row.
+        /// </summary>
+        /// <typeparam name="T">Type of the key. Must match the dictionary's element type.</typeparam>
+        /// <param name="key">Key to assign to this row.</param>
+        protected void SetKey<T>(T key)
+        {
+            parent.SetKey(rowIdx, key);
+        }
+
         /// <summary>
         /// <summary>
         /// Gets the value contained in this dictionary's row.
         /// Gets the value contained in this dictionary's row.
         /// </summary>
         /// </summary>
@@ -818,7 +883,7 @@ namespace BansheeEditor
         /// <returns>Value in this dictionary's row.</returns>
         /// <returns>Value in this dictionary's row.</returns>
         protected T GetValue<T>()
         protected T GetValue<T>()
         {
         {
-            return (T)parent.GetValueInternal(key);
+            return (T)parent.GetValueInternal(rowIdx);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -828,7 +893,7 @@ namespace BansheeEditor
         /// <param name="value">Value to set.</param>
         /// <param name="value">Value to set.</param>
         protected void SetValue<T>(T value)
         protected void SetValue<T>(T value)
         {
         {
-            parent.SetValueInternal(key, value);
+            parent.SetValueInternal(rowIdx, value);
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 9 - 2
MBansheeEditor/Inspectors/GUISkinInspector.cs

@@ -87,11 +87,13 @@ namespace BansheeEditor
             /// <inheritdoc/>
             /// <inheritdoc/>
             protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
             protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
             {
             {
+                string key = GetKey<string>();
+
                 GUILayoutX titleLayout = layout.AddLayoutX();
                 GUILayoutX titleLayout = layout.AddLayoutX();
                 keyField = new GUITextField(new LocEdString((string)key));
                 keyField = new GUITextField(new LocEdString((string)key));
                 titleLayout.AddElement(keyField);
                 titleLayout.AddElement(keyField);
 
 
-                // TODO - Key changes are not being applied yet
+                keyField.OnChanged += SetKey;
 
 
                 return titleLayout;
                 return titleLayout;
             }
             }
@@ -109,7 +111,12 @@ namespace BansheeEditor
             {
             {
                 rebuildGUI = false;
                 rebuildGUI = false;
 
 
-                // TODO - Ignoring the case if the GUIElementStyle reference changes
+                string newKey = GetKey<string>();
+                if (keyField.Value != newKey)
+                {
+                    keyField.Value = newKey;
+                    return true;
+                }
 
 
                 // Key cannot be changed so we don't check it here
                 // Key cannot be changed so we don't check it here
                 return valueField.Refresh();
                 return valueField.Refresh();

+ 13 - 3
MBansheeEditor/Inspectors/StringTableInspector.cs

@@ -110,11 +110,13 @@ namespace BansheeEditor
             /// <inheritdoc/>
             /// <inheritdoc/>
             protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
             protected override GUILayoutX CreateKeyGUI(GUILayoutY layout)
             {
             {
+                string key = GetKey<string>();
+
                 GUILayoutX titleLayout = layout.AddLayoutX();
                 GUILayoutX titleLayout = layout.AddLayoutX();
-                keyField = new GUITextField(new LocEdString((string)key));
+                keyField = new GUITextField(new LocEdString(key));
                 titleLayout.AddElement(keyField);
                 titleLayout.AddElement(keyField);
 
 
-                // TODO - Key changes are not being applied yet
+                keyField.OnChanged += SetKey;
 
 
                 return titleLayout;
                 return titleLayout;
             }
             }
@@ -126,6 +128,8 @@ namespace BansheeEditor
 
 
                 valueField = new GUITextField(new LocEdString(value));
                 valueField = new GUITextField(new LocEdString(value));
                 layout.AddElement(valueField);
                 layout.AddElement(valueField);
+
+                valueField.OnChanged += SetValue;
             }
             }
 
 
             /// <inheritdoc/>
             /// <inheritdoc/>
@@ -133,7 +137,13 @@ namespace BansheeEditor
             {
             {
                 rebuildGUI = false;
                 rebuildGUI = false;
 
 
-                // Key cannot be changed so we don't check it here
+                string newKey = GetKey<string>();
+                if (keyField.Value != newKey)
+                {
+                    keyField.Value = newKey;
+                    return true;
+                }
+
                 string newValue = GetValue<string>();
                 string newValue = GetValue<string>();
                 if (valueField.Value != newValue)
                 if (valueField.Value != newValue)
                 {
                 {