Browse Source

Improve drag/drop mechanics, support dragging nodes around in hierarchy frame to reparent

Josh Engebretson 10 years ago
parent
commit
76b5f061cc

+ 49 - 5
Script/AtomicEditor/ui/HierarchyFrame.ts

@@ -52,7 +52,7 @@ class HierarchyFrame extends Atomic.UIWidget {
 
 
         var parentID = this.nodeIDToItemID[node.parent.id];
         var parentID = this.nodeIDToItemID[node.parent.id];
 
 
-        var childItemID = this.hierList.addChildItem(parentID, node.name, "Folder.icon", node.id.toString());
+        var childItemID = this.recursiveAddNode(parentID, node);
 
 
         this.nodeIDToItemID[node.id] = childItemID;
         this.nodeIDToItemID[node.id] = childItemID;
 
 
@@ -71,7 +71,7 @@ class HierarchyFrame extends Atomic.UIWidget {
 
 
         this.hierList.deleteItemByID(node.id.toString());
         this.hierList.deleteItemByID(node.id.toString());
 
 
-        this.sendEvent("EditorActiveNodeChange", { node: ev.parent ? ev.parent : this.scene});
+        this.sendEvent("EditorActiveNodeChange", { node: ev.parent ? ev.parent : this.scene });
 
 
     }
     }
 
 
@@ -136,8 +136,50 @@ class HierarchyFrame extends Atomic.UIWidget {
 
 
                 var selectedId = Number(list.selectedItemID);
                 var selectedId = Number(list.selectedItemID);
                 var node = this.scene.getNode(selectedId);
                 var node = this.scene.getNode(selectedId);
-                this.hierList.rootList.dragObject = new Atomic.UIDragObject(node, node.name.length ? node.name : "(Anonymous)");
-                this.sendEvent("EditorActiveNodeChange", { node: node });
+
+                if (node) {
+
+                    // set the widget's drag object
+                    var dragObject = new Atomic.UIDragObject(node, node.name.length ? "Node: " + node.name : "Node: (Anonymous)");
+                    this.hierList.rootList.dragObject = dragObject;
+
+                    // handle dropping on hierarchy, moving node
+                    this.subscribeToEvent(dragObject, "DragEnded", (ev: Atomic.DragEndedEvent) => {
+
+                        var dragNode = <Atomic.Node> ev.dragObject.object;
+                        var dropNode: Atomic.Node = this.scene.getNode(Number(this.hierList.hoverItemID));
+
+                        if (!dropNode) {
+                            return;
+                        }
+
+                        // can't drop on self
+                        if (dragNode == dropNode) {
+                            return;
+                        }
+
+                        // check if dropping on child of ourselves
+                        var parent = dropNode.parent;
+
+                        while (parent) {
+
+                            if (parent == dragNode) {
+                                return;
+                            }
+
+                            parent = parent.parent;
+
+                        }
+
+                        // move it
+                        dropNode.addChild(dragNode);
+
+                    });
+
+                    this.sendEvent("EditorActiveNodeChange", { node: node });
+
+                }
+
                 return false;
                 return false;
 
 
             }
             }
@@ -146,7 +188,7 @@ class HierarchyFrame extends Atomic.UIWidget {
         return false;
         return false;
     }
     }
 
 
-    recursiveAddNode(parentID: number, node: Atomic.Node) {
+    recursiveAddNode(parentID: number, node: Atomic.Node):number {
 
 
         //if (node.isTemporary())
         //if (node.isTemporary())
         //  return;
         //  return;
@@ -166,6 +208,8 @@ class HierarchyFrame extends Atomic.UIWidget {
 
 
         }
         }
 
 
+        return childItemID;
+
     }
     }
 
 
     populate() {
     populate() {

+ 4 - 0
Script/TypeScript/Atomic.d.ts

@@ -7116,6 +7116,8 @@ declare module Atomic {
 
 
    export class UIListView extends UIWidget {
    export class UIListView extends UIWidget {
 
 
+      hoverItemID: string;
+      selectedItemID: string;
       rootList: UISelectList;
       rootList: UISelectList;
 
 
       // Construct.
       // Construct.
@@ -7128,6 +7130,8 @@ declare module Atomic {
       setExpanded(itemID: number, value: boolean): void;
       setExpanded(itemID: number, value: boolean): void;
       deleteAllItems(): void;
       deleteAllItems(): void;
       selectItemByID(id: string): void;
       selectItemByID(id: string): void;
+      getHoverItemID(): string;
+      getSelectedItemID(): string;
       getRootList(): UISelectList;
       getRootList(): UISelectList;
 
 
    }
    }

+ 23 - 0
Script/TypeScript/AtomicWork.d.ts

@@ -63,6 +63,29 @@ declare module Atomic {
         widget: UIWidget;
         widget: UIWidget;
     }
     }
 
 
+    export interface DragBeginEvent {
+
+        source: UIWidget;
+        dragObject: UIDragObject;
+    }
+
+    export interface DragEnterWidgetEvent {
+
+        widget: UIWidget;
+        dragObject: UIDragObject;
+    }
+
+    export interface DragExitWidgetEvent {
+
+        widget: UIWidget;
+        dragObject: UIDragObject;
+    }
+
+    export interface DragEndedEvent {
+
+        target: UIWidget;
+        dragObject: UIDragObject;
+    }
 
 
     export interface AttributeInfo {
     export interface AttributeInfo {
 
 

+ 18 - 17
Source/Atomic/UI/UIDragDrop.cpp

@@ -68,6 +68,7 @@ void UIDragDrop::DragEnd()
     // clean up
     // clean up
     currentTargetWidget_ = 0;
     currentTargetWidget_ = 0;
     dragObject_ = 0;
     dragObject_ = 0;
+    dragSelectObject_ = 0;
     dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
     dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
 
 
     if (currentTargetWidget.Null())
     if (currentTargetWidget.Null())
@@ -78,7 +79,7 @@ void UIDragDrop::DragEnd()
     VariantMap dropData;
     VariantMap dropData;
     dropData[DragEnded::P_TARGET] = currentTargetWidget;
     dropData[DragEnded::P_TARGET] = currentTargetWidget;
     dropData[DragEnded::P_DRAGOBJECT] = dragObject;
     dropData[DragEnded::P_DRAGOBJECT] = dragObject;
-    SendEvent(E_DRAGENDED, dropData);
+    dragObject->SendEvent(E_DRAGENDED, dropData);
 }
 }
 
 
 void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
 void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
@@ -107,19 +108,7 @@ void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
 
 
         currentTargetWidget_ = widget;
         currentTargetWidget_ = widget;
 
 
-        if (widget->GetType() == UISelectList::GetTypeStatic())
-        {
-            // handle select drag
-
-            dragObject_ = widget->GetDragObject();
-
-            LOGINFOF("DRAG Select: %s, DragObject: %s", widget->GetTypeName().CString(),
-                                                        dragObject_.Null() ? "NULL" : dragObject_->GetTypeName().CString());
-        }
-        else
-        {
-            dragObject_ = widget->GetDragObject();
-        }
+        dragSelectObject_ = widget->GetDragObject();
 
 
     }
     }
 
 
@@ -129,6 +118,8 @@ void UIDragDrop::HandleMouseUp(StringHash eventType, VariantMap& eventData)
 {
 {
     using namespace MouseButtonUp;
     using namespace MouseButtonUp;
 
 
+    dragSelectObject_ = 0;
+
     if (dragObject_.Null())
     if (dragObject_.Null())
         return;
         return;
 
 
@@ -141,12 +132,22 @@ void UIDragDrop::HandleMouseUp(StringHash eventType, VariantMap& eventData)
 
 
 void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 {
 {
-    if (dragObject_.Null())
-        return;
-
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
 
 
     if (!input->IsMouseVisible())
     if (!input->IsMouseVisible())
+    {
+        dragObject_ = 0;
+        dragSelectObject_ = 0;
+        return;
+    }
+
+    if (dragSelectObject_.NotNull())
+    {
+        dragObject_ = dragSelectObject_;
+        dragSelectObject_ = 0;
+    }
+
+    if (dragObject_.Null())
         return;
         return;
 
 
     // initialize if necessary
     // initialize if necessary

+ 2 - 0
Source/Atomic/UI/UIDragDrop.h

@@ -44,6 +44,8 @@ private:
 
 
     SharedPtr<UIDragObject> dragObject_;
     SharedPtr<UIDragObject> dragObject_;
 
 
+    SharedPtr<UIDragObject> dragSelectObject_;
+
 };
 };
 
 
 
 

+ 3 - 0
Source/Atomic/UI/UIListView.h

@@ -34,6 +34,9 @@ public:
     void DeleteAllItems();
     void DeleteAllItems();
     void SelectItemByID(const String& id);
     void SelectItemByID(const String& id);
 
 
+    String GetHoverItemID() { return rootList_.Null() ? "" : rootList_->GetHoverItemID(); }
+    String GetSelectedItemID() { return rootList_.Null() ? "" : rootList_->GetSelectedItemID(); }
+
     UISelectList* GetRootList() { return rootList_; }
     UISelectList* GetRootList() { return rootList_; }
 
 
 private:
 private: