Selaa lähdekoodia

Fixed UI subsystem to dismiss the FileSelector correctly when its modal window is being closed via ESC key.

Wei Tjong Yao 12 vuotta sitten
vanhempi
sitoutus
2f88f7fc81

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

@@ -12,7 +12,6 @@ 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");
 const int LABEL_WIDTH = 30;
 
 // Constants for accessing xmlResources
@@ -378,23 +377,13 @@ void PostEditAttribute(Array<Serializable@>@ serializables, uint index, const Ar
     SaveEditActionGroup(group);
 
     // If a UI-element changing its 'Is Modal' attribute, clear the hierarchy list selection
-    bool testModalElement = false;
     int itemType = GetType(serializables[0]);
     if (itemType == ITEM_UI_ELEMENT && serializables[0].attributeInfos[index].name == "Is Modal")
-    {
         hierarchyList.ClearSelection();
-        testModalElement = true;
-    }
 
     for (uint i = 0; i < serializables.length; ++i)
     {
         PostEditAttribute(serializables[i], index);
-
-        // 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 (testModalElement)
-            cast<UIElement>(serializables[i]).vars[NO_AUTO_REMOVE] = true;
-
         if (itemType == ITEM_UI_ELEMENT)
             SetUIElementModified(serializables[i]);
     }

+ 0 - 1
Bin/Data/UI/DefaultStyle.xml

@@ -196,7 +196,6 @@
         <attribute name="Layout Mode" value="vertical" />
         <attribute name="Layout Spacing" value="4" />
         <attribute name="Layout Border" value="6 6 6 6" />
-        <attribute name="Is Modal" value="true" />
         <attribute name="Modal Shade Color" value="0.45 0.70 0.45 0.05" />
         <attribute name="Modal Frame Color" value="0.45 0.70 0.45" />
         <attribute name="Modal Frame Size" value="2 2" />

+ 1 - 1
Docs/GettingStarted.dox

@@ -78,7 +78,7 @@ To run from Xcode on iPhone/iPad Simulator, edit the Product Scheme to set "Run"
 
 \section Building_64bit Desktop 64bit build
 
-Currently CMake build configuration has been set to compile Urho3D as 32bit by default. To enable 64bit build for Visual Studio, run one of the cmake_vs20xx.bat by passing the option "Win64" explicitly. This will overrides CMake to use a 64bit solution generator.
+Currently CMake build configuration has been set to compile Urho3D as 32bit by default. To enable 64bit build for Visual Studio, run one of the cmake_vs20xx.bat by passing the option "Win64" explicitly. This overrides CMake to use a 64bit solution generator.
 
 To enable 64bit build for non-MSVC/non-Windows platform, pass the option "-DENABLE_64BIT=1" explicitly when invoking cmake_eclipse.sh/cmake_macosx.sh/cmake_gcc.sh. Alternatively, you can modify the main CMakeLists.txt to enable 64bit by default for non-MSVC/non-Windows platform.
 

+ 5 - 1
Engine/UI/FileSelector.cpp

@@ -123,7 +123,7 @@ FileSelector::FileSelector(Context* context) :
     {
         ui->GetRoot()->AddChild(window_);
         ui->SetFocusElement(fileList_);
-        window_->BringToFront();
+        window_->SetModal(true);
     }
 
     SubscribeToEvent(filterList_, E_ITEMSELECTED, HANDLER(FileSelector, HandleFilterChanged));
@@ -135,6 +135,7 @@ FileSelector::FileSelector(Context* context) :
     SubscribeToEvent(okButton_, E_RELEASED, HANDLER(FileSelector, HandleOKPressed));
     SubscribeToEvent(cancelButton_, E_RELEASED, HANDLER(FileSelector, HandleCancelPressed));
     SubscribeToEvent(closeButton_, E_RELEASED, HANDLER(FileSelector, HandleCancelPressed));
+    SubscribeToEvent(window_, E_MODALCHANGED, HANDLER(FileSelector, HandleCancelPressed));
 }
 
 FileSelector::~FileSelector()
@@ -496,6 +497,9 @@ void FileSelector::HandleCancelPressed(StringHash eventType, VariantMap& eventDa
     if (ignoreEvents_)
         return;
 
+    if (eventType == E_MODALCHANGED && eventData[ModalChanged::P_MODAL].GetBool())
+        return;
+
     using namespace FileSelected;
 
     VariantMap newEventData;

+ 10 - 17
Engine/UI/UI.cpp

@@ -61,7 +61,6 @@ 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");
 
 const char* UI_CATEGORY = "UI";
 
@@ -83,10 +82,10 @@ UI::UI(Context* context) :
 {
     rootElement_->SetTraversalMode(TM_DEPTH_FIRST);
     rootModalElement_->SetTraversalMode(TM_DEPTH_FIRST);
-    
+
     // Register UI library object factories
     RegisterUILibrary(context_);
-    
+
     SubscribeToEvent(E_SCREENMODE, HANDLER(UI, HandleScreenMode));
     SubscribeToEvent(E_MOUSEBUTTONDOWN, HANDLER(UI, HandleMouseButtonDown));
     SubscribeToEvent(E_MOUSEBUTTONUP, HANDLER(UI, HandleMouseButtonUp));
@@ -97,7 +96,7 @@ UI::UI(Context* context) :
     SubscribeToEvent(E_TOUCHMOVE, HANDLER(UI, HandleTouchMove));
     SubscribeToEvent(E_KEYDOWN, HANDLER(UI, HandleKeyDown));
     SubscribeToEvent(E_CHAR, HANDLER(UI, HandleChar));
-    
+
     // Try to initialize right now, but skip if screen mode is not yet set
     Initialize();
 }
@@ -374,17 +373,17 @@ void UI::RenderUpdate()
 void UI::Render()
 {
     PROFILE(RenderUI);
-    
+
     SetVertexData(vertexBuffer_, vertexData_);
     SetVertexData(debugVertexBuffer_, debugVertexData_);
-    
+
     // Render non-modal batches
     Render(vertexBuffer_, batches_, 0, nonModalBatchSize_);
     // Render debug draw
     Render(debugVertexBuffer_, debugDrawBatches_, 0, debugDrawBatches_.Size());
     // Render modal batches
     Render(vertexBuffer_, batches_, nonModalBatchSize_, batches_.Size());
-    
+
     // Clear the debug draw batches and data
     debugDrawBatches_.Clear();
     debugVertexData_.Clear();
@@ -559,13 +558,13 @@ void UI::SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData)
 {
     if (vertexData.Empty())
         return;
-    
+
     // Update quad geometry into the vertex buffer
     // Resize the vertex buffer first if too small or much too large
     unsigned numVertices = vertexData.Size() / UI_VERTEX_SIZE;
     if (dest->GetVertexCount() < numVertices || dest->GetVertexCount() > numVertices * 2)
         dest->SetSize(numVertices, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1, true);
-    
+
     dest->SetData(&vertexData[0]);
 }
 
@@ -597,7 +596,7 @@ void UI::Render(VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigne
     graphics_->SetStencilTest(false);
     graphics_->ResetRenderTargets();
     graphics_->SetVertexBuffer(buffer);
-    
+
     ShaderVariation* ps = 0;
     ShaderVariation* vs = 0;
 
@@ -1126,16 +1125,10 @@ void UI::HandleKeyDown(StringHash eventType, VariantMap& eventData)
             SetFocusElement(0);
         else
         {
-            // If it is a modal window, by resetting its modal flag and auto-remove it
+            // If it is a modal window, by resetting its modal flag
             Window* window = dynamic_cast<Window*>(element);
             if (window)
-            {
                 window->SetModal(false);
-                if (window->GetVars().Contains(VAR_NO_AUTO_REMOVE))
-                    const_cast<VariantMap&>(window->GetVars()).Erase(VAR_NO_AUTO_REMOVE);
-                else
-                    window->Remove();
-            }
         }
 
         return;

+ 7 - 7
Engine/UI/UIElement.cpp

@@ -1192,20 +1192,18 @@ void UIElement::InsertChild(unsigned index, UIElement* element)
 
 void UIElement::RemoveChild(UIElement* element, unsigned index)
 {
-    UIElement* root = GetRoot();
-    UIElement* sender = GetElementEventSender();
-
     for (unsigned i = index; i < children_.Size(); ++i)
     {
         if (children_[i] == element)
         {
             // Send change event if not already being destroyed
-            if (Refs() > 0 && sender)
+            UIElement* sender = Refs() > 0 ? GetElementEventSender() : 0;
+            if (sender)
             {
                 using namespace ElementRemoved;
 
                 VariantMap eventData;
-                eventData[P_ROOT] = (void*)root;
+                eventData[P_ROOT] = (void*)GetRoot();
                 eventData[P_PARENT] = (void*)this;
                 eventData[P_ELEMENT] = (void*)element;
 
@@ -1233,11 +1231,12 @@ void UIElement::RemoveChildAtIndex(unsigned index)
 void UIElement::RemoveAllChildren()
 {
     UIElement* root = GetRoot();
+    UIElement* sender = Refs() > 0 ? GetElementEventSender() : 0;
 
     for (Vector<SharedPtr<UIElement> >::Iterator i = children_.Begin(); i < children_.End(); )
     {
         // Send change event if not already being destroyed
-        if (Refs() > 0 && root)
+        if (sender)
         {
             using namespace ElementRemoved;
 
@@ -1246,12 +1245,13 @@ void UIElement::RemoveAllChildren()
             eventData[P_PARENT] = (void*)this;
             eventData[P_ELEMENT] = (void*)(*i).Get();
 
-            root->SendEvent(E_ELEMENTREMOVED, eventData);
+            sender->SendEvent(E_ELEMENTREMOVED, eventData);
         }
 
         (*i++)->Detach();
     }
     children_.Clear();
+    UpdateLayout();
 }
 
 void UIElement::Remove()

+ 9 - 2
Engine/UI/UIEvents.h

@@ -158,6 +158,13 @@ EVENT(E_VIEWCHANGED, ViewChanged)
     PARAM(P_Y, Y);                          // int
 }
 
+/// UI modal changed (currently only Window has modal flag).
+EVENT(E_MODALCHANGED, ModalChanged)
+{
+    PARAM(P_ELEMENT, Element);              // UIElement pointer
+    PARAM(P_MODAL, Modal);                  // bool
+}
+
 /// Editable text changed
 EVENT(E_TEXTCHANGED, TextChanged)
 {
@@ -221,7 +228,7 @@ EVENT(E_FILESELECTED, FileSelected)
     PARAM(P_OK, Ok);                        // bool
 }
 
-/// A child element has been added to an element. Sent by the UI root element.
+/// A child element has been added to an element. Sent by the UI root element, or element-event-sender if set.
 EVENT(E_ELEMENTADDED, ElementAdded)
 {
     PARAM(P_ROOT, Root);                    // UIElement pointer
@@ -229,7 +236,7 @@ EVENT(E_ELEMENTADDED, ElementAdded)
     PARAM(P_ELEMENT, Element);              // UIElement pointer
 }
 
-/// A child element is about to be removed from an element. Sent by the UI root element.
+/// A child element is about to be removed from an element. Sent by the UI root element, or element-event-sender if set.
 EVENT(E_ELEMENTREMOVED, ElementRemoved)
 {
     PARAM(P_ROOT, Root);                    // UIElement pointer

+ 13 - 2
Engine/UI/Window.cpp

@@ -25,6 +25,7 @@
 #include "Cursor.h"
 #include "InputEvents.h"
 #include "UI.h"
+#include "UIEvents.h"
 #include "Window.h"
 
 #include "DebugNew.h"
@@ -221,10 +222,20 @@ void Window::SetResizeBorder(const IntRect& rect)
 
 void Window::SetModal(bool modal)
 {
-    UI* ui = GetSubsystem<UI>();
     // UI may be null at shutdown if for example a script was holding a reference to this window
-    if (ui && ui->SetModalElement(this, modal))
+    UI* ui = GetSubsystem<UI>();
+    if (!ui)
+        return;
+
+    if (ui->SetModalElement(this, modal))
         modal_ = modal;
+
+    using namespace ModalChanged;
+
+    VariantMap eventData;
+    eventData[P_ELEMENT] = (void*)this;
+    eventData[P_MODAL] = modal;
+    SendEvent(E_MODALCHANGED, eventData);
 }
 
 void Window::SetModalShadeColor(const Color& color)

+ 0 - 4
Engine/UI/Window.h

@@ -129,10 +129,6 @@ protected:
     Color modalFrameColor_;
     /// Modal frame size, used when modal flag is set.
     IntVector2 modalFrameSize_;
-
-private:
-    /// Handle modal window being focused.
-    void HandleModalFocused(StringHash eventType, VariantMap& eventData);
 };
 
 }

+ 3 - 3
Readme.txt

@@ -239,8 +239,8 @@ Desktop 64bit build
 
 Currently CMake build configuration has been set to compile Urho3D as 32bit by
 default. To enable 64bit build for Visual Studio, run one of the cmake_vs20xx.bat
-by passing the option "Win64" explicitly. This will overrides CMake to use a
-64bit solution generator.
+by passing the option "Win64" explicitly. This overrides CMake to use a 64bit
+solution generator.
 
 To enable 64bit build for non-MSVC/non-Windows platform, pass the
 option "-DENABLE_64BIT=1" explicitly when invoking cmake_eclipse.sh/
@@ -358,4 +358,4 @@ V1.1    - Object and scene model refactoring.
         - Added OpenGL and cross-platform support.
         - Switched to kNet library for networking.
 
-V1.0    - Original release.
+V1.0    - Original release.