Browse Source

Further fine tuning on the UI subsystem.

Wei Tjong Yao 12 years ago
parent
commit
17714cb198

+ 5 - 4
Bin/Data/Scripts/Editor/EditorNodeWindow.as

@@ -14,6 +14,7 @@ const String STRIKED_OUT = "——";   // Two unicode EM DASH (U+2014)
 const ShortStringHash NODE_IDS_VAR("NodeIDs");
 const ShortStringHash COMPONENT_IDS_VAR("ComponentIDs");
 const ShortStringHash UI_ELEMENT_IDS_VAR("UIElementIDs");
+const ShortStringHash NO_AUTO_REMOVE("NoAutoRemove");
 
 uint nodeContainerIndex = M_MAX_UNSIGNED;
 uint componentContainerStartIndex = 0;
@@ -305,12 +306,11 @@ void PostEditAttribute(Array<Serializable@>@ serializables, uint index, const Ar
         action.Define(serializables[i], index, oldValues[i]);
         group.actions.Push(action);
     }
-
     SaveEditActionGroup(group);
 
     // If a UI-element changing its 'Is Modal' attribute, clear the hierarchy list selection
     bool saveModalElement = false;
-    if (serializables[0].attributeInfos[index].name == "Is Modal")
+    if (GetType(serializables[0]) == ITEM_UI_ELEMENT && serializables[0].attributeInfos[index].name == "Is Modal")
     {
         hierarchyList.ClearSelection();
         saveModalElement = true;
@@ -320,9 +320,10 @@ void PostEditAttribute(Array<Serializable@>@ serializables, uint index, const Ar
     {
         PostEditAttribute(serializables[i], index);
 
-        // Need to save a reference of the modal element being tested as otherwise there is no way to get it back when it is being dismissed by ESC key
+        // Set a user-defined var to prevent auto-removal of the modal element being tested in the editor
+        // After losing the modal flag, the modal element should be reparented to its original parent automatically
         if (saveModalElement)
-            modalUIElements.Push(serializables[i]);
+            cast<UIElement>(serializables[i]).vars[NO_AUTO_REMOVE] = true;
     }
 }
 

+ 1 - 1
Bin/Data/Scripts/Editor/EditorSceneWindow.as

@@ -1020,7 +1020,7 @@ bool SelectAll()
     {
         if (!selectedNodes.empty || !selectedComponents.empty)
             return SceneSelectAll();
-        else if (!selectedUIElements.empty)
+        else if (!selectedUIElements.empty || hierarchyList.items[GetListIndex(editorUIElement)].selected)
             return UIElementSelectAll();
         else
             return SceneSelectAll();    // If nothing is selected yet, fall back to scene select all

+ 0 - 11
Bin/Data/Scripts/Editor/EditorUI.as

@@ -990,15 +990,4 @@ void UpdateDirtyUI()
     // Perform some event-triggered updates latently in case a large hierarchy was changed
     if (attributesFullDirty || attributesDirty)
         UpdateAttributeInspector(attributesFullDirty);
-    
-    for (uint i = 0; i < modalUIElements.length; ++i)
-    {
-        // If it is detached then reparent it to editor root UI element
-        if (modalUIElements[i].parent is null)
-        {
-            editorUIElement.AddChild(modalUIElements[i]);
-            modalUIElements.Erase(i);
-            break;  // Only one at a time
-        }
-    }
 }

+ 9 - 4
Bin/Data/Scripts/Editor/EditorUIElement.as

@@ -8,7 +8,6 @@ String childElementFileName;
 UIElement@ editUIElement;
 Array<Serializable@> selectedUIElements;
 Array<Serializable@> editUIElements;
-Array<UIElement@> modalUIElements;
 
 Array<XMLFile@> uiElementCopyBuffer;
 
@@ -436,10 +435,16 @@ bool UIElementDelete()
 bool UIElementSelectAll()
 {
     BeginSelectionModify();
-    Array<UIElement@> elements = editorUIElement.GetChildren(true);
     Array<uint> indices;
-    for (uint i = 0; i < elements.length; ++i)
-        indices.Push(GetListIndex(elements[i]));
+    uint baseIndex = GetListIndex(editorUIElement);
+    indices.Push(baseIndex);
+    int baseIndent = hierarchyList.items[baseIndex].indent;
+    for (uint i = baseIndex + 1; i < hierarchyList.numItems; ++i)
+    {
+        if (hierarchyList.items[i].indent <= baseIndent)
+            break;
+        indices.Push(i);
+    }
     hierarchyList.SetSelections(indices);
     EndSelectionModify();
 

+ 30 - 30
Docs/ScriptAPI.dox

@@ -3161,12 +3161,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 
 Properties:<br>
 - ShortStringHash type (readonly)
@@ -3222,7 +3222,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3272,12 +3272,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 
@@ -3335,7 +3335,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3386,8 +3386,8 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
-- const Variant& GetVar(const ShortStringHash&)
 - UIElement@ GetElementEventSender() const
+- const Variant& GetVar(const ShortStringHash&)
 - void SetPosition(float, float)
 - void SetHotSpot(int, int)
 - void SetScale(float, float)
@@ -3424,7 +3424,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - float derivedOpacity (readonly)
 - VariantMap vars (readonly)
@@ -3479,12 +3479,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void SetPressedOffset(int, int)
@@ -3545,7 +3545,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3605,12 +3605,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void SetCheckedOffset(int, int)
@@ -3669,7 +3669,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3727,12 +3727,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void DefineShape(CursorShape, Texture@, const IntRect&, const IntVector2&, bool arg4 = false)
@@ -3791,7 +3791,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3848,12 +3848,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void ChangeValue(float)
@@ -3912,7 +3912,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -3973,12 +3973,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void ChangeValue(float)
 - void StepBack()
 - void StepForward()
@@ -4037,7 +4037,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4096,12 +4096,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetViewPosition(int, int)
 - void SetScrollBarsVisible(bool, bool)
 
@@ -4159,7 +4159,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4217,12 +4217,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetViewPosition(int, int)
 - void SetScrollBarsVisible(bool, bool)
 - void AddItem(UIElement@)
@@ -4297,7 +4297,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4367,12 +4367,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - bool SetFont(const String&, int)
 - bool SetFont(Font@, int)
 - void SetSelection(uint, uint arg1 = M_MAX_UNSIGNED)
@@ -4432,7 +4432,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4494,12 +4494,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 
@@ -4557,7 +4557,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4624,12 +4624,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void SetPressedOffset(int, int)
@@ -4692,7 +4692,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4757,12 +4757,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 - void SetPressedOffset(int, int)
@@ -4831,7 +4831,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)
@@ -4901,12 +4901,12 @@ Methods:<br>
 - UIElement@ GetChild(const String&, bool arg1 = false) const
 - UIElement@ GetChild(const ShortStringHash&, const Variant& arg1 = Variant ( ), bool arg2 = false) const
 - UIElement@[]@ GetChildren(bool arg0 = false) const
+- UIElement@ GetElementEventSender() const
 - const Variant& GetVar(const ShortStringHash&)
 - IntVector2 ScreenToElement(const IntVector2&)
 - IntVector2 ElementToScreen(const IntVector2&)
 - bool IsInside(IntVector2, bool)
 - bool IsInsideCombined(IntVector2, bool)
-- UIElement@ GetElementEventSender() const
 - void SetFullImageRect()
 - void SetHoverOffset(int, int)
 
@@ -4964,7 +4964,7 @@ Properties:<br>
 - uint[] numChildren (readonly)
 - uint numAllChildren (readonly)
 - UIElement@[] children (readonly)
-- UIElement@ parent (readonly)
+- UIElement@ parent
 - UIElement@ root (readonly)
 - IntVector2 screenPosition (readonly)
 - IntRect combinedScreenRect (readonly)

+ 2 - 1
Engine/Engine/APITemplates.h

@@ -857,6 +857,7 @@ template <class T> void RegisterUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "UIElement@+ GetChild(const String&in, bool recursive = false) const", asMETHODPR(T, GetChild, (const String&, bool) const, UIElement*), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "UIElement@+ GetChild(const ShortStringHash&in, const Variant&in value = Variant(), bool recursive = false) const", asMETHODPR(T, GetChild, (const ShortStringHash&, const Variant&, bool) const, UIElement*), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "Array<UIElement@>@ GetChildren(bool recursive = false) const", asFUNCTION(UIElementGetChildren), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "UIElement@+ GetElementEventSender() const", asMETHOD(T, GetElementEventSender), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const Variant& GetVar(const ShortStringHash&in)", asMETHOD(T, GetVar), asCALL_THISCALL);
     if (!isSprite)
     {
@@ -969,11 +970,11 @@ template <class T> void RegisterUIElement(asIScriptEngine* engine, const char* c
     }
     engine->RegisterObjectMethod(className, "void set_elementEventSender(bool)", asMETHOD(T, SetElementEventSender), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_elementEventSender() const", asMETHOD(T, IsElementEventSender), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "UIElement@+ GetElementEventSender() const", asMETHOD(T, GetElementEventSender), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "uint get_numChildren() const", asFUNCTION(UIElementGetNumChildrenNonRecursive), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "uint get_numAllChildren() const", asFUNCTION(UIElementGetNumChildrenRecursive), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "uint get_numChildren(bool) const", asMETHOD(T, GetNumChildren), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "UIElement@+ get_children(uint) const", asMETHODPR(T, GetChild, (unsigned) const, UIElement*), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void set_parent(UIElement@+, uint arg1 = M_MAX_UNSIGNED)", asMETHOD(T, SetParent), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "UIElement@+ get_parent() const", asMETHOD(T, GetParent), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "UIElement@+ get_root() const", asMETHOD(T, GetRoot), asCALL_THISCALL);
     if (!isSprite)

+ 20 - 7
Engine/UI/UI.cpp

@@ -58,7 +58,9 @@ namespace Urho3D
 
 ShortStringHash VAR_ORIGIN("Origin");
 const ShortStringHash VAR_ORIGINAL_PARENT("OriginalParent");
+const ShortStringHash VAR_ORIGINAL_CHILD_INDEX("OriginalChildIndex");
 const ShortStringHash VAR_PARENT_CHANGED("ParentChanged");
+const ShortStringHash VAR_NO_AUTO_REMOVE("NoAutoRemove");
 
 OBJECTTYPESTATIC(UI);
 
@@ -197,7 +199,9 @@ bool UI::SetModalElement(UIElement* modalElement, bool enable)
         }
 
         // Adopt modal root as parent
-        modalElement->SetVar(VAR_ORIGINAL_PARENT, modalElement->GetParent());
+        UIElement* oriParent = modalElement->GetParent();
+        modalElement->SetVar(VAR_ORIGINAL_PARENT, oriParent);
+        modalElement->SetVar(VAR_ORIGINAL_CHILD_INDEX, oriParent ? oriParent->FindChild(modalElement) : M_MAX_UNSIGNED);
         modalElement->SetParent(rootModalElement_);
 
         // If it is a popup element, bring along its top-level parent
@@ -210,7 +214,9 @@ bool UI::SetModalElement(UIElement* modalElement, bool enable)
             if (element)
             {
                 originElement->SetVar(VAR_PARENT_CHANGED, element);
-                element->SetVar(VAR_ORIGINAL_PARENT, element->GetParent());
+                oriParent = element->GetParent();
+                element->SetVar(VAR_ORIGINAL_PARENT, oriParent);
+                element->SetVar(VAR_ORIGINAL_CHILD_INDEX, oriParent ? oriParent->FindChild(element) : M_MAX_UNSIGNED);
                 element->SetParent(rootModalElement_);
             }
         }
@@ -225,8 +231,10 @@ bool UI::SetModalElement(UIElement* modalElement, bool enable)
             if (children[i] == modalElement)
             {
                 // Revert back to original parent
-                modalElement->SetParent(static_cast<UIElement*>(modalElement->GetVar(VAR_ORIGINAL_PARENT).GetPtr()));
-                const_cast<VariantMap&>(modalElement->GetVars()).Erase(VAR_ORIGINAL_PARENT);
+                modalElement->SetParent(static_cast<UIElement*>(modalElement->GetVar(VAR_ORIGINAL_PARENT).GetPtr()), modalElement->GetVar(VAR_ORIGINAL_CHILD_INDEX).GetUInt());
+                VariantMap& vars = const_cast<VariantMap&>(modalElement->GetVars());
+                vars.Erase(VAR_ORIGINAL_PARENT);
+                vars.Erase(VAR_ORIGINAL_CHILD_INDEX);
 
                 // If it is a popup element, revert back its top-level parent to its original parent
                 UIElement* originElement = static_cast<UIElement*>(modalElement->GetVar(VAR_ORIGIN).GetPtr());
@@ -236,8 +244,10 @@ bool UI::SetModalElement(UIElement* modalElement, bool enable)
                     if (element)
                     {
                         const_cast<VariantMap&>(originElement->GetVars()).Erase(VAR_PARENT_CHANGED);
-                        element->SetParent(static_cast<UIElement*>(element->GetVar(VAR_ORIGINAL_PARENT).GetPtr()));
-                        const_cast<VariantMap&>(element->GetVars()).Erase(VAR_ORIGINAL_PARENT);
+                        element->SetParent(static_cast<UIElement*>(element->GetVar(VAR_ORIGINAL_PARENT).GetPtr()), element->GetVar(VAR_ORIGINAL_CHILD_INDEX).GetUInt());
+                        vars = const_cast<VariantMap&>(element->GetVars());
+                        vars.Erase(VAR_ORIGINAL_PARENT);
+                        vars.Erase(VAR_ORIGINAL_CHILD_INDEX);
                     }
                 }
 
@@ -1082,7 +1092,10 @@ void UI::HandleKeyDown(StringHash eventType, VariantMap& eventData)
             if (window)
             {
                 window->SetModal(false);
-                window->Remove();
+                if (window->GetVars().Contains(VAR_NO_AUTO_REMOVE))
+                    const_cast<VariantMap&>(window->GetVars()).Erase(VAR_NO_AUTO_REMOVE);
+                else
+                    window->Remove();
             }
         }
 

+ 4 - 1
Engine/UI/UI.h

@@ -52,7 +52,10 @@ public:
     void SetCursor(Cursor* cursor);
     /// Set focused UI element.
     void SetFocusElement(UIElement* element);
-    /// Set modal element. Until all the modal elements are dismissed, all the inputs and events are only sent to them. Return true when successful. Only the modal element can clear its modal status or when it is being destructed.
+    /// Set modal element. Until all the modal elements are dismissed, all the inputs and events are only sent to them. Return true when successful.
+    /// Only the modal element can clear its modal status or when it is being destructed.
+    /// UI subystem auto-removes modal element when an ESC key is pressed, however if this is not desirable, setting a user-defined variable "NoAutoRemove" in the modal element would prevent this.
+    /// In that case, the modal element will only have its modal flag reset and reparented back to its original parent.
     bool SetModalElement(UIElement* modalElement, bool enable);
     /// Clear the UI (excluding the cursor.)
     void Clear();

+ 2 - 2
Engine/UI/UIElement.cpp

@@ -1142,10 +1142,10 @@ unsigned UIElement::FindChild(UIElement* element) const
     return i != children_.End() ? i - children_.Begin() : M_MAX_UNSIGNED;
 }
 
-void UIElement::SetParent(UIElement* parent)
+void UIElement::SetParent(UIElement* parent, unsigned index)
 {
     if (parent)
-        parent->AddChild(this);
+        parent->InsertChild(index, this);
 }
 
 void UIElement::SetVar(ShortStringHash key, const Variant& value)

+ 2 - 2
Engine/UI/UIElement.h

@@ -290,8 +290,8 @@ public:
     void Remove();
     /// Find child index. Return M_MAX_UNSIGNED if not found.
     unsigned FindChild(UIElement* element) const;
-    /// Set parent element. Same as parent->AddChild(this).
-    void SetParent(UIElement* parent);
+    /// Set parent element. Same as parent->InsertChild(index, this).
+    void SetParent(UIElement* parent, unsigned index = M_MAX_UNSIGNED);
     /// Set a user variable.
     void SetVar(ShortStringHash key, const Variant& value);
     /// Mark as internally (programmatically) created. Used when an element composes itself out of child elements.