Browse Source

Async loading of prefab resources when dragging/dropping, support drag enter/exit events

Josh Engebretson 10 years ago
parent
commit
9b349cc1eb

+ 44 - 20
Source/Atomic/UI/UIDragDrop.cpp

@@ -62,33 +62,23 @@ UIDragDrop::~UIDragDrop()
 
 void UIDragDrop::DragEnd()
 {
-    Input* input = GetSubsystem<Input>();
-
-    if (!input->IsMouseVisible())
-        return;
+    SharedPtr<UIDragObject> dragObject = dragObject_;
+    SharedPtr<UIWidget> currentTargetWidget = currentTargetWidget_;
 
-    // see if we have a widget
-    TBWidget* tbw = TBWidget::hovered_widget;
+    // clean up
+    currentTargetWidget_ = 0;
+    dragObject_ = 0;
+    dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
 
-    while(tbw && !tbw->GetDelegate())
+    if (currentTargetWidget.Null())
     {
-        tbw = tbw->GetParent();
-    }
-
-    if (!tbw)
         return;
-
-    UIWidget* widget = (UIWidget*) tbw->GetDelegate();
+    }
 
     VariantMap dropData;
-    dropData[DragEnded::P_TARGET] = widget;
-    dropData[DragEnded::P_DRAGOBJECT] = dragObject_;
+    dropData[DragEnded::P_TARGET] = currentTargetWidget;
+    dropData[DragEnded::P_DRAGOBJECT] = dragObject;
     SendEvent(E_DRAGENDED, dropData);
-
-    // clean up
-    dragObject_ = 0;
-    dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
-
 }
 
 void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
@@ -115,6 +105,8 @@ void UIDragDrop::HandleMouseDown(StringHash eventType, VariantMap& eventData)
 
         UIWidget* widget = (UIWidget*) tbw->GetDelegate();
 
+        currentTargetWidget_ = widget;
+
         if (widget->GetType() == UISelectList::GetTypeStatic())
         {
             // handle select drag
@@ -169,6 +161,38 @@ void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
     int x = eventData[P_X].GetInt();
     int y = eventData[P_Y].GetInt();
 
+    // see if we have a widget
+    TBWidget* tbw = TBWidget::hovered_widget;
+
+    while(tbw && !tbw->GetDelegate())
+    {
+        tbw = tbw->GetParent();
+    }
+
+    if (!tbw)
+        return;
+
+    UIWidget* hoverWidget = (UIWidget*) tbw->GetDelegate();
+
+    if (hoverWidget != currentTargetWidget_)
+    {
+        if (currentTargetWidget_)
+        {
+            VariantMap exitData;
+            exitData[DragExitWidget::P_WIDGET] = currentTargetWidget_;
+            exitData[DragExitWidget::P_DRAGOBJECT] = dragObject_;
+            SendEvent(E_DRAGEXITWIDGET, exitData);
+        }
+
+        currentTargetWidget_ = hoverWidget;
+
+        VariantMap enterData;
+        enterData[DragEnterWidget::P_WIDGET] = currentTargetWidget_;
+        enterData[DragEnterWidget::P_DRAGOBJECT] = dragObject_;
+        SendEvent(E_DRAGENTERWIDGET, enterData);
+
+    }
+
     dragLayout_->SetPosition(x, y - 20);
 
 }

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

@@ -35,10 +35,13 @@ private:
 
     void DragEnd();
 
+    // attached to mouse UI
     SharedPtr<UILayout> dragLayout_;
     SharedPtr<UIImageWidget> dragImage_;
     SharedPtr<UITextField> dragText_;
 
+    SharedPtr<UIWidget> currentTargetWidget_;
+
     SharedPtr<UIDragObject> dragObject_;
 
 };

+ 18 - 0
Source/Atomic/UI/UIEvents.h

@@ -58,6 +58,24 @@ EVENT(E_WIDGETDELETED, WidgetDeleted)
     PARAM(P_WIDGET, Widget);             // UIWidget pointer
 }
 
+EVENT(E_DRAGBEGIN, DragBegin)
+{
+    PARAM(P_TARGET, Source);             // UIWidget source
+    PARAM(P_DRAGOBJECT, DragObject);     // UIDragObject pointer
+}
+
+EVENT(E_DRAGENTERWIDGET, DragEnterWidget)
+{
+    PARAM(P_WIDGET, Widget);             // UIWidget pointer
+    PARAM(P_DRAGOBJECT, DragObject);     // UIDragObject pointer
+}
+
+EVENT(E_DRAGEXITWIDGET, DragExitWidget)
+{
+    PARAM(P_WIDGET, Widget);             // UIWidget pointer
+    PARAM(P_DRAGOBJECT, DragObject);     // UIDragObject pointer
+}
+
 EVENT(E_DRAGENDED, DragEnded)
 {
     PARAM(P_TARGET, Target);             // UIWidget pointer

+ 102 - 8
Source/AtomicEditorWork/Editors/SceneEditor3D/SceneView3D.cpp

@@ -28,6 +28,8 @@
 #include <Atomic/UI/UI.h>
 #include <Atomic/UI/UIEvents.h>
 
+#include <Atomic/Resource/ResourceEvents.h>
+
 #include <ToolCore/Assets/Asset.h>
 #include <ToolCore/Assets/AssetDatabase.h>
 
@@ -89,8 +91,14 @@ SceneView3D ::SceneView3D(Context* context, SceneEditor3D *sceneEditor) :
     SubscribeToEvent(E_UPDATE, HANDLER(SceneView3D, HandleUpdate));
     SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneView3D, HandleEditorActiveNodeChange));
     SubscribeToEvent(E_POSTRENDERUPDATE, HANDLER(SceneView3D, HandlePostRenderUpdate));
+
+    SubscribeToEvent(E_MOUSEMOVE, HANDLER(SceneView3D,HandleMouseMove));
+
+    SubscribeToEvent(E_DRAGENTERWIDGET, HANDLER(SceneView3D, HandleDragEnterWidget));
+    SubscribeToEvent(E_DRAGEXITWIDGET, HANDLER(SceneView3D, HandleDragExitWidget));
     SubscribeToEvent(E_DRAGENDED, HANDLER(SceneView3D, HandleDragEnded));
 
+
     // TODO: generate this event properly
     VariantMap eventData;
     eventData[EditorActiveSceneChange::P_SCENE] = scene_;
@@ -345,6 +353,25 @@ void SceneView3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
         MoveCamera(timeStep);
 
     QueueUpdate();
+
+    if (preloadResourceScene_.NotNull())
+    {
+        if (preloadResourceScene_->GetAsyncProgress() == 1.0f)
+        {
+            ResourceCache* cache = GetSubsystem<ResourceCache>();
+            XMLFile* xml = cache->GetResource<XMLFile>(dragAssetGUID_);
+
+            if (dragNode_.NotNull())
+            {
+                dragNode_->LoadXML(xml->GetRoot());
+                UpdateDragNode(0, 0);
+            }
+            preloadResourceScene_ = 0;
+            dragAssetGUID_ = "";
+
+        }
+    }
+
 }
 
 void SceneView3D::HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData)
@@ -353,11 +380,44 @@ void SceneView3D::HandleEditorActiveNodeChange(StringHash eventType, VariantMap&
     SelectNode(node);
 }
 
-void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
+void SceneView3D::UpdateDragNode(int mouseX, int mouseY)
+{
+    if (dragNode_.Null())
+        return;
+
+    Ray ray = GetCameraRay();
+
+    Vector3 pos = ray.origin_;
+    pos += ray.direction_ * 10;
+
+    dragNode_->SetWorldPosition(pos);
+
+}
+
+void SceneView3D::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 {
-    using namespace DragEnded;
+    if (dragNode_.Null())
+        return;
+
+    Input* input = GetSubsystem<Input>();
+
+    if (!input->IsMouseVisible())
+        return;
 
-    UIWidget* widget = static_cast<UIWidget*>(eventData[P_TARGET].GetPtr());
+    using namespace MouseMove;
+
+    int x = eventData[P_X].GetInt();
+    int y = eventData[P_Y].GetInt();
+
+    UpdateDragNode(x, y);
+
+}
+
+void SceneView3D::HandleDragEnterWidget(StringHash eventType, VariantMap& eventData)
+{
+    using namespace DragEnterWidget;
+
+    UIWidget* widget = static_cast<UIWidget*>(eventData[P_WIDGET].GetPtr());
 
     if (widget != this)
         return;
@@ -373,22 +433,56 @@ void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
     {
         Asset* asset = (Asset*) object;
 
-        ResourceCache* cache = GetSubsystem<ResourceCache>();
+        AssetDatabase* db = GetSubsystem<AssetDatabase>();
 
         const String& importer = asset->GetImporterTypeName();
 
         if (importer == "ModelImporter")
         {
-            Node* node = scene_->CreateChild(asset->GetName());
-            XMLFile* xml = cache->GetResource<XMLFile>(asset->GetGUID());
-            node->LoadXML(xml->GetRoot());
+            dragNode_ = scene_->CreateChild(asset->GetName());
+
+            preloadResourceScene_ = new Scene(context_);
+
+            SharedPtr<File> file(new File(context_, db->GetCachePath() + asset->GetGUID()));
+
+            preloadResourceScene_->LoadAsyncXML(file, LOAD_RESOURCES_ONLY);
+            dragAssetGUID_ = asset->GetGUID();
+
+            Input* input = GetSubsystem<Input>();
+            IntVector2 pos = input->GetMousePosition();
+
+            UpdateDragNode(pos.x_, pos.y_);
+
         }
 
-        LOGINFOF("Dropped %s : %s on SceneView3D", asset->GetPath().CString(), asset->GetGUID().CString());
+        //LOGINFOF("Dropped %s : %s on SceneView3D", asset->GetPath().CString(), asset->GetGUID().CString());
     }
 
 }
 
+void SceneView3D::HandleDragExitWidget(StringHash eventType, VariantMap& eventData)
+{
+    if (preloadResourceScene_.NotNull())
+    {
+        preloadResourceScene_->StopAsyncLoading();
+        preloadResourceScene_ = 0;
+    }
+
+    if (dragNode_.NotNull())
+    {
+        scene_->RemoveChild(dragNode_);
+    }
+
+    dragAssetGUID_ = 0;
+    dragNode_ = 0;
+}
+
+
+void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
+{
+    dragNode_ = 0;
+}
+
 
 
 }

+ 11 - 0
Source/AtomicEditorWork/Editors/SceneEditor3D/SceneView3D.h

@@ -51,7 +51,14 @@ private:
 
     bool MouseInView();
 
+    void HandleMouseMove(StringHash eventType, VariantMap& eventData);
+
+    void UpdateDragNode(int mouseX, int mouseY);
+
     void HandleDragEnded(StringHash eventType, VariantMap& eventData);
+    void HandleDragExitWidget(StringHash eventType, VariantMap& eventData);
+    void HandleDragEnterWidget(StringHash eventType, VariantMap& eventData);
+
     void HandleUpdate(StringHash eventType, VariantMap& eventData);
     void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData);    
     void HandleEditorActiveNodeChange(StringHash eventType, VariantMap& eventData);
@@ -75,6 +82,10 @@ private:
     SharedPtr<Octree> octree_;
     SharedPtr<Node> selectedNode_;
 
+    SharedPtr<Scene> preloadResourceScene_;
+    String dragAssetGUID_;
+    SharedPtr<Node> dragNode_;
+
 };
 
 }