Forráskód Böngészése

Implement GetElementAt() exclusion with modal element without dynamic allocation.
Fixed popup element of a modal window not getting input.
GetVar() code shortening.

Lasse Öörni 12 éve
szülő
commit
49b7b15ea6
4 módosított fájl, 31 hozzáadás és 28 törlés
  1. 1 4
      Engine/Scene/Node.cpp
  2. 4 4
      Engine/UI/Menu.cpp
  3. 25 16
      Engine/UI/UI.cpp
  4. 1 4
      Engine/UI/UIElement.cpp

+ 1 - 4
Engine/Scene/Node.cpp

@@ -864,10 +864,7 @@ bool Node::HasComponent(ShortStringHash type) const
 const Variant& Node::GetVar(ShortStringHash key) const
 {
     VariantMap::ConstIterator i = vars_.Find(key);
-    if (i != vars_.End())
-        return i->second_;
-    else
-        return Variant::EMPTY;
+    return i != vars_.End() ? i->second_ : Variant::EMPTY;
 }
 
 Component* Node::GetComponent(ShortStringHash type) const

+ 4 - 4
Engine/UI/Menu.cpp

@@ -33,7 +33,7 @@
 namespace Urho3D
 {
 
-static const ShortStringHash originHash("Origin");
+extern ShortStringHash VAR_ORIGIN;
 
 OBJECTTYPESTATIC(Menu);
 
@@ -254,7 +254,7 @@ void Menu::ShowPopup(bool enable)
             root->AddChild(popup_);
         popup_->SetPosition(GetScreenPosition() + popupOffset_);
         popup_->SetVisible(true);
-        popup_->SetVar(originHash, (void*)this);
+        popup_->SetVar(VAR_ORIGIN, (void*)this);
         popup_->BringToFront();
     }
     else
@@ -269,7 +269,7 @@ void Menu::ShowPopup(bool enable)
                 menu->ShowPopup(false);
         }
 
-        popup_->SetVar(originHash, Variant::EMPTY);
+        popup_->SetVar(VAR_ORIGIN, Variant::EMPTY);
         popup_->SetVisible(false);
         popup_->Remove();
     }
@@ -345,7 +345,7 @@ void Menu::HandleFocusChanged(StringHash eventType, VariantMap& eventData)
         if (element == this || element == popup_)
             return;
         if (element->GetParent() == root)
-            element = static_cast<UIElement*>(element->GetVar(originHash).GetPtr());
+            element = static_cast<UIElement*>(element->GetVar(VAR_ORIGIN).GetPtr());
         else
             element = element->GetParent();
     }

+ 25 - 16
Engine/UI/UI.cpp

@@ -56,6 +56,8 @@
 namespace Urho3D
 {
 
+ShortStringHash VAR_ORIGIN("Origin");
+
 OBJECTTYPESTATIC(UI);
 
 UI::UI(Context* context) :
@@ -439,22 +441,7 @@ void UI::SetNonFocusedMouseWheel(bool nonFocusedMouseWheel)
 UIElement* UI::GetElementAt(const IntVector2& position, bool enabledOnly)
 {
     UIElement* result = 0;
-    if (modalElement_)
-    {
-        // Create temporary root which only contains the modal element
-        SharedPtr<UIElement> fakeRoot(new UIElement(context_));
-
-        // Special care is needed to insert into fakeRoot without altering the actual modal element's parent
-        Vector<SharedPtr<UIElement> >& children = const_cast<Vector<SharedPtr<UIElement> >& >(fakeRoot->GetChildren());
-        children.Push(SharedPtr<UIElement>(modalElement_));
-
-        GetElementAt(result, fakeRoot, position, enabledOnly);
-
-        // Special care is needed to clear the children vector before the shared pointer goes out of scope to prevent it from detaching modal element
-        children.Clear();
-    }
-    else
-        GetElementAt(result, rootElement_, position, enabledOnly);
+    GetElementAt(result, rootElement_, position, enabledOnly);
     return result;
 }
 
@@ -600,6 +587,28 @@ void UI::GetElementAt(UIElement*& result, UIElement* current, const IntVector2&
     for (unsigned i = 0; i < children.Size(); ++i)
     {
         UIElement* element = children[i];
+        // If has a modal element, skip other elements from the root level
+        // Exception: if the element has the "origin" element in its variables it is a popup and should not be skipped
+        // if the origin element belongs to the modal element's hierarchy
+        if (current == rootElement_ && modalElement_ && element != modalElement_)
+        {
+            bool shouldSkip = true;
+            UIElement* originElement = static_cast<UIElement*>(element->GetVar(VAR_ORIGIN).GetPtr());
+            
+            while (originElement)
+            {
+                if (originElement == modalElement_)
+                {
+                    shouldSkip = false;
+                    break;
+                }
+                originElement = originElement->GetParent();
+            }
+            
+            if (shouldSkip)
+                continue;
+        }
+        
         bool hasChildren = element->GetNumChildren() > 0;
 
         if (element != cursor_.Get() && element->IsVisible())

+ 1 - 4
Engine/UI/UIElement.cpp

@@ -1271,10 +1271,7 @@ const Color& UIElement::GetDerivedColor() const
 const Variant& UIElement::GetVar(const ShortStringHash& key) const
 {
     VariantMap::ConstIterator i = vars_.Find(key);
-    if (i != vars_.End())
-        return i->second_;
-    else
-        return Variant::EMPTY;
+    return i != vars_.End() ? i->second_ : Variant::EMPTY;
 }
 
 IntVector2 UIElement::ScreenToElement(const IntVector2& screenPosition)