浏览代码

Initial UI drag and drop support. No visualization yet.

Lasse Öörni 15 年之前
父节点
当前提交
f2492935d4
共有 6 个文件被更改,包括 67 次插入3 次删除
  1. 2 0
      Engine/Engine/RegisterTemplates.h
  2. 4 0
      Engine/Engine/RegisterUI.cpp
  3. 25 3
      Engine/UI/UI.cpp
  4. 14 0
      Engine/UI/UIElement.cpp
  5. 15 0
      Engine/UI/UIElement.h
  6. 7 0
      Engine/UI/UIEvents.h

+ 2 - 0
Engine/Engine/RegisterTemplates.h

@@ -444,6 +444,7 @@ template <class T> void registerUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "void setFocus(bool)", asMETHOD(T, setFocus), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setSelected(bool)", asMETHOD(T, setSelected), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setVisible(bool)", asMETHOD(T, setVisible), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void setDragDropMode(uint)", asMETHOD(T, setDragDropMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setUserData(const VariantMap& in)", asMETHOD(T, setUserData), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setStyleAuto(XMLFile@+)", asFUNCTION(UIElementSetStyleAuto<T>), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "void setLayout(LayoutMode, int, const IntRect&)", asMETHOD(T, setLayout), asCALL_THISCALL);
@@ -484,6 +485,7 @@ template <class T> void registerUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "bool isVisible() const", asMETHOD(T, isVisible), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool isHovering() const", asMETHOD(T, isHovering), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool hasColorGradient() const", asMETHOD(T, hasColorGradient), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "uint getDragDropMode() const", asMETHOD(T, getDragDropMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const VariantMap& getUserData() const", asMETHOD(T, getUserData), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "LayoutMode getLayoutMode() const", asMETHOD(T, getLayoutMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int getLayoutSpacing() const", asMETHOD(T, getLayoutSpacing), asCALL_THISCALL);

+ 4 - 0
Engine/Engine/RegisterUI.cpp

@@ -79,6 +79,10 @@ static void registerUIElement(asIScriptEngine* engine)
     engine->RegisterEnumValue("LayoutMode", "LM_HORIZONTAL", LM_HORIZONTAL);
     engine->RegisterEnumValue("LayoutMode", "LM_VERTICAL", LM_VERTICAL);
     
+    engine->RegisterGlobalProperty("const uint DD_DISABLED", (void*)&DD_DISABLED);
+    engine->RegisterGlobalProperty("const uint DD_SOURCE", (void*)&DD_SOURCE);
+    engine->RegisterGlobalProperty("const uint DD_TARGET", (void*)&DD_TARGET);
+    
     registerUIElement<UIElement>(engine, "UIElement");
     
     // Register static function for getting UI style XML element

+ 25 - 3
Engine/UI/UI.cpp

@@ -509,7 +509,7 @@ void UI::handleMouseButtonDown(StringHash eventType, VariantMap& eventData)
             if (button == MOUSEB_LEFT)
             {
                 setFocusElement(element);
-                // Must check the pointer after each operation, because any UI event may trigger its destruction
+                // Verify existence after each operation, because any calls/events may potentially destroy the element
                 if (element)
                     element->bringToFront();
             }
@@ -547,10 +547,32 @@ void UI::handleMouseButtonUp(StringHash eventType, VariantMap& eventData)
         
         if ((mMouseDrag) && (!mMouseButtons))
         {
-            UIElement* element = verifyElement(mMouseDragElement);
+            WeakPtr<UIElement> element(verifyElement(mMouseDragElement));
             if ((element) && (element->isEnabled()) && (element->isVisible()))
+            {
                 element->onDragEnd(element->screenToElement(pos), pos);
-            
+                
+                // Check for drag and drop. Verify existence after each operation, because any calls/events may potentially destroy
+                // the elements
+                if ((element) && (element->getDragDropMode() & DD_SOURCE))
+                {
+                    WeakPtr<UIElement> target(getElementAt(pos));
+                    if ((target) && (target != element) && (target->getDragDropMode() & DD_TARGET))
+                    {
+                        target->onDrop(element);
+                        
+                        if ((target) && (element))
+                        {
+                            using namespace UIDragDrop;
+                            
+                            VariantMap eventData;
+                            eventData[P_SOURCE] = element;
+                            eventData[P_TARGET] = target;
+                            sendEvent(EVENT_UIDRAGDROP, eventData);
+                        }
+                    }
+                }
+            }
             mMouseDrag = false;
             mMouseDragElement = 0;
         }

+ 14 - 0
Engine/UI/UIElement.cpp

@@ -46,6 +46,7 @@ UIElement::UIElement(const std::string& name) :
     mSelected(false),
     mVisible(true),
     mHovering(false),
+    mDragDropMode(DD_DISABLED),
     mLayoutMode(LM_FREE),
     mLayoutSpacing(0),
     mLayoutBorder(IntRect::sZero),
@@ -183,6 +184,10 @@ void UIElement::setStyle(const XMLElement& element, ResourceCache* cache)
         setSelected(element.getChildElement("selected").getBool("enable"));
     if (element.hasChildElement("visible"))
         setVisible(element.getChildElement("visible").getBool("enable"));
+    if (element.hasChildElement("dragdropmode"))
+        setDragDropMode(element.getChildElement("dragdropmode").getInt("value"));
+    if (element.hasChildElement("userdata"))
+        setUserData(element.getChildElement("userdat").getVariantMap());
     if (element.hasChildElement("layout"))
     {
         XMLElement layoutElem = element.getChildElement("layout");
@@ -306,6 +311,10 @@ void UIElement::onDragEnd(const IntVector2& position, const IntVector2& screenPo
 {
 }
 
+void UIElement::onDrop(UIElement* source)
+{
+}
+
 void UIElement::onWheel(int delta, int buttons, int qualifiers)
 {
 }
@@ -602,6 +611,11 @@ void UIElement::setVisible(bool enable)
     }
 }
 
+void UIElement::setDragDropMode(unsigned mode)
+{
+    mDragDropMode = mode;
+}
+
 void UIElement::setUserData(const VariantMap& userData)
 {
     mUserData = userData;

+ 15 - 0
Engine/UI/UIElement.h

@@ -88,6 +88,13 @@ enum LayoutMode
     LM_VERTICAL
 };
 
+//! Drag and drop disabled
+static const unsigned DD_DISABLED = 0;
+//! Drag and drop source flag
+static const unsigned DD_SOURCE = 1;
+//! Drag and drop target flag
+static const unsigned DD_TARGET = 2;
+
 class ResourceCache;
 
 //! Base class for UI elements
@@ -122,6 +129,8 @@ public:
     virtual void onDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers);
     //! React to mouse drag end
     virtual void onDragEnd(const IntVector2& position, const IntVector2& screenPosition);
+    //! React to drag and drop finish
+    virtual void onDrop(UIElement* element);
     //! React to mouse wheel
     virtual void onWheel(int delta, int buttons, int qualifiers);
     //! React to a key press
@@ -207,6 +216,8 @@ public:
     void setSelected(bool enable);
     //! Set whether is visible
     void setVisible(bool enable);
+    //! Set drag and drop flags
+    void setDragDropMode(unsigned mode);
     //! Set userdata
     void setUserData(const VariantMap& userData);
     //! Set style from an XML file. Find the style element automatically
@@ -288,6 +299,8 @@ public:
     bool isHovering() const { return mHovering; }
     //! Return whether has different color in at least one corner
     bool hasColorGradient() const { return mHasColorGradient; }
+    //! Return drag and drop flags
+    unsigned getDragDropMode() const { return mDragDropMode; }
     //! Return userdata
     VariantMap& getUserData() { return mUserData; }
     //! Return layout mode
@@ -375,6 +388,8 @@ protected:
     bool mVisible;
     //! Hovering flag
     bool mHovering;
+    //! Drag and drop flags
+    unsigned mDragDropMode;
     //! Userdata
     VariantMap mUserData;
     //! Layout mode

+ 7 - 0
Engine/UI/UIEvents.h

@@ -37,6 +37,13 @@ DEFINE_EVENT(EVENT_UIMOUSECLICK, UIMouseClick)
     EVENT_PARAM(P_QUALIFIERS, Qualifiers);      // int
 }
 
+//! Drag and drop
+DEFINE_EVENT(EVENT_UIDRAGDROP, UIDragDrop)
+{
+    EVENT_PARAM(P_SOURCE, Source);              // UIElement pointer
+    EVENT_PARAM(P_TARGET, Target);              // UIElement pointer
+};
+
 //! UI element resized
 DEFINE_EVENT(EVENT_RESIZED, Resized)
 {