Browse Source

Able to drag from finder to project list and import FBX with materials preserved

Josh Engebretson 10 years ago
parent
commit
ec5a78d68b

+ 48 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/ProjectFrame.ts

@@ -31,6 +31,7 @@ class ProjectFrame extends ScriptWidget {
 
         // events
         this.subscribeToEvent("ProjectLoaded", (data) => this.handleProjectLoaded(data));
+        this.subscribeToEvent("DragEnded", (data) => this.handleDragEnded(data));
 
     }
 
@@ -90,6 +91,50 @@ class ProjectFrame extends ScriptWidget {
 
     }
 
+    handleDragEnded(data) {
+
+      var dragObject = <Atomic.UIDragObject> data.dragObject;
+      var filenames = dragObject.filenames;
+
+      if (!filenames.length)
+        return;
+
+      // if the drop target is the folderList's root select widget
+      var rootList = this.folderList.rootList;
+
+      var hoverID = rootList.hoverItemID;
+
+      if ( hoverID != "") {
+
+        var db = ToolCore.getAssetDatabase();
+        var fileSystem = Atomic.getFileSystem();
+        var asset = db.getAssetByGUID(hoverID);
+
+        if (asset && asset.isFolder) {
+
+          for (var i in filenames) {
+
+            var srcFilename = filenames[i];
+
+            var pathInfo = Atomic.splitPath(srcFilename);
+
+            var destFilename = Atomic.addTrailingSlash(asset.path);
+
+            destFilename += pathInfo.fileName + pathInfo.ext;
+
+            fileSystem.copy(srcFilename, destFilename);
+
+          }
+
+          db.scan();
+          this.refresh();
+          this.refreshContent(asset);
+
+        }
+
+      }
+
+    }
 
     handleProjectLoaded(data) {
 
@@ -142,6 +187,9 @@ class ProjectFrame extends ScriptWidget {
 
     refresh() {
 
+        var container = this.getWidget("contentcontainer");
+        container.deleteAllChildren();
+
         var system = ToolCore.getToolSystem();
         var project = system.project;
 

+ 1 - 1
Source/Atomic/CMakeLists.txt

@@ -52,7 +52,7 @@ endif()
 
 if (APPLE)
     if (NOT IOS)
-      set (PLATFORM_SOURCE IO/MacFileWatcher.mm)
+        set (PLATFORM_SOURCE IO/MacFileWatcher.mm UI/UIDragDropMac.mm)
     else()
     endif()
 endif()

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

@@ -16,6 +16,12 @@
 #include "UIDragDrop.h"
 #include "UIDragObject.h"
 
+#ifdef ATOMIC_PLATFORM_OSX
+
+#include "UIDragDropMac.h"
+
+#endif
+
 using namespace tb;
 
 namespace Atomic
@@ -45,6 +51,8 @@ UIDragDrop::UIDragDrop(Context* context) : Object(context)
     TBWidget* root = GetSubsystem<UI>()->GetRootWidget();
     root->AddChild(dragLayout_->GetInternalWidget());
 
+    InitDragAndDrop(this);
+
 }
 
 UIDragDrop::~UIDragDrop()
@@ -52,6 +60,37 @@ UIDragDrop::~UIDragDrop()
 
 }
 
+void UIDragDrop::DragEnd()
+{
+    Input* input = GetSubsystem<Input>();
+
+    if (!input->IsMouseVisible())
+        return;
+
+    // see if we have a widget
+    TBWidget* tbw = TBWidget::hovered_widget;
+
+    while(tbw && !tbw->GetDelegate())
+    {
+        tbw = tbw->GetParent();
+    }
+
+    if (!tbw)
+        return;
+
+    UIWidget* widget = (UIWidget*) tbw->GetDelegate();
+
+    VariantMap dropData;
+    dropData[DragEnded::P_TARGET] = widget;
+    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)
 {
     using namespace MouseButtonDown;
@@ -97,25 +136,10 @@ void UIDragDrop::HandleMouseUp(StringHash eventType, VariantMap& eventData)
     if (dragObject_.Null())
         return;
 
-    Input* input = GetSubsystem<Input>();
-
-    if (!input->IsMouseVisible())
+    if (!(eventData[P_BUTTON].GetInt() ==  MOUSEB_LEFT))
         return;
 
-    if ((eventData[P_BUTTON].GetInt() ==  MOUSEB_LEFT) &&
-            TBWidget::hovered_widget && TBWidget::hovered_widget->GetDelegate())
-    {
-        UIWidget* widget = (UIWidget*) TBWidget::hovered_widget->GetDelegate();
-
-        VariantMap dropData;
-        dropData[DragEnded::P_TARGET] = widget;
-        dropData[DragEnded::P_DRAGOBJECT] = dragObject_;
-        SendEvent(E_DRAGENDED, dropData);
-    }
-
-    // clean up
-    dragObject_ = 0;
-    dragLayout_->SetVisibility(UI_WIDGET_VISIBILITY_GONE);
+    DragEnd();
 
 }
 
@@ -149,4 +173,21 @@ void UIDragDrop::HandleMouseMove(StringHash eventType, VariantMap& eventData)
 
 }
 
+void UIDragDrop::FileDragEntered()
+{
+    dragObject_ = new UIDragObject(context_);
+    //dragObject_->SetText("Files...");
+}
+
+void UIDragDrop::FileDragAddFile(const String& filename)
+{
+    dragObject_->AddFilename(filename);
+}
+
+void UIDragDrop::FileDragConclude()
+{
+    DragEnd();
+}
+
+
 }

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

@@ -23,12 +23,18 @@ public:
     UIDragDrop(Context* context);
     virtual ~UIDragDrop();
 
+    void FileDragEntered();
+    void FileDragAddFile(const String& filename);
+    void FileDragConclude();
+
 private:
 
     void HandleMouseDown(StringHash eventType, VariantMap& eventData);
     void HandleMouseUp(StringHash eventType, VariantMap& eventData);
     void HandleMouseMove(StringHash eventType, VariantMap& eventData);
 
+    void DragEnd();
+
     SharedPtr<UILayout> dragLayout_;
     SharedPtr<UIImageWidget> dragImage_;
     SharedPtr<UITextField> dragText_;

+ 11 - 0
Source/Atomic/UI/UIDragDropMac.h

@@ -0,0 +1,11 @@
+
+#pragma once
+
+namespace Atomic
+{
+
+class UIDragDrop;
+
+void InitDragAndDrop(UIDragDrop *dragAndDrop);
+
+}

+ 162 - 0
Source/Atomic/UI/UIDragDropMac.mm

@@ -0,0 +1,162 @@
+#include <stdio.h>
+
+#include <ThirdParty/SDL/include/SDL.h>
+#include <ThirdParty/SDL/include/SDL_syswm.h>
+
+#include <Atomic/IO/Log.h>
+#include <Atomic/Input/InputEvents.h>
+#include <Atomic/Graphics/Graphics.h>
+
+#include "UIDragDrop.h"
+#include "UIDragDropMac.h"
+
+static Atomic::WeakPtr<Atomic::UIDragDrop> dragAndDrop_;
+
+@interface NSWindow (NSWindowWithDragAndDrop)
+
+    -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
+    -(NSDragOperation)draggingUpdated:(id)sender;
+    -(BOOL)prepareForDragOperation:(id)sender;
+    -(BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
+    -(void)concludeDragOperation:(id <NSDraggingInfo>)sender;
+@end
+
+@implementation NSWindow (NSWindowWithDragAndDrop)
+
+-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+    NSPasteboard *pboard = [sender draggingPasteboard];
+    NSString *type = [pboard availableTypeFromArray:[NSArray arrayWithObject:NSFilenamesPboardType]];
+    if (type)
+    {
+        if ([type isEqualToString:NSFilenamesPboardType])
+        {
+            NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
+            int i = (int) [filenames count];
+
+            if (i)
+                dragAndDrop_->FileDragEntered();
+
+            while (i-- > 0)
+            {
+                NSString *filename = [filenames objectAtIndex:i];
+                dragAndDrop_->FileDragAddFile([filename UTF8String]);
+            }
+
+        }
+    }
+
+    return NSDragOperationCopy;
+}
+
+-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+    using namespace Atomic::MouseMove;
+
+    Atomic::Graphics* graphics = dragAndDrop_->GetSubsystem<Atomic::Graphics>();
+
+    NSPoint dragPoint = [sender draggingLocation];
+
+    Atomic::VariantMap eventData;
+    eventData[P_X] = (int) dragPoint.x;
+    eventData[P_Y] = graphics->GetHeight() - (int) dragPoint.y;
+    eventData[P_DX] = 0;
+    eventData[P_DY] = 0;
+    eventData[P_BUTTONS] = 0;
+    eventData[P_QUALIFIERS] = 0;
+
+    dragAndDrop_->SendEvent(Atomic::E_MOUSEMOVE, eventData);
+
+    return NSDragOperationCopy;
+}
+
+-(BOOL)prepareForDragOperation:(id)sender
+{
+    return YES;
+}
+
+-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+    return YES;
+}
+
+-(void)concludeDragOperation:(id <NSDraggingInfo>)sender
+{
+    dragAndDrop_->FileDragConclude();
+}
+
+@end
+
+namespace Atomic
+{
+
+static NSWindow* GetNSWindow()
+{
+    SDL_Window* window = (SDL_Window*) dragAndDrop_->GetSubsystem<Graphics>()->GetSDLWindow();
+
+    SDL_SysWMinfo info;
+    SDL_VERSION(&info.version);
+
+    if(SDL_GetWindowWMInfo(window, &info)) {
+
+        return info.info.cocoa.window;
+    }
+
+    return NULL;
+}
+
+/*
+void StartDragAndDrop()
+{
+    Object* o = dragAndDrop_->GetDragObject();
+
+    if (!o)
+        return;
+
+    ToolCore::Asset* asset = o->GetType() == ToolCore::Asset::GetTypeStatic() ? (ToolCore::Asset*) o : NULL;
+
+    if (asset)
+    {
+        NSWindow* window = GetNSWindow();
+        if (window)
+        {
+
+            NSImage *dragImage = nil;
+            NSPoint dragPosition;
+            NSString* filePath = [NSString stringWithUTF8String:asset->GetPath().CString()];
+
+            // Write data to the pasteboard
+
+            NSArray *fileList = [NSArray arrayWithObjects:filePath, nil];
+            NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+            [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
+                    owner:nil];
+            [pboard setPropertyList:fileList forType:NSFilenamesPboardType];
+
+            // blocks
+            [window dragImage:dragImage
+                    at:dragPosition
+                    offset:NSZeroSize
+                    event:nil
+                    pasteboard:pboard
+                    source:window
+                    slideBack:YES];
+
+        }
+    }
+}
+*/
+
+void InitDragAndDrop(UIDragDrop *dragAndDrop)
+{
+    dragAndDrop_ = dragAndDrop;
+
+    NSWindow* window = GetNSWindow();
+    if (window)
+    {
+        [window registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
+    }
+
+}
+
+}

+ 5 - 0
Source/Atomic/UI/UIDragObject.h

@@ -21,14 +21,19 @@ public:
     const String& GetIcon() { return icon_; }
     Object* GetObject() { return object_; }
 
+    const Vector<String>& GetFilenames() { return filenames_; }
+
     void SetText(const String& text) { text_ = text; }
     void SetIcon(const String& icon) { icon_ = icon; }
     void SetObject(Object* object) { object_ = object; }
 
+    void AddFilename(const String& filename) {filenames_.Push(filename); }
+
 private:
 
     String text_;
     String icon_;
+    Vector<String> filenames_;
     SharedPtr<Object> object_;
 
 };

+ 22 - 0
Source/Atomic/UI/UISelectList.cpp

@@ -79,6 +79,28 @@ String UISelectList::GetSelectedItemID()
 
 }
 
+String UISelectList::GetHoverItemID()
+{
+    if (!widget_)
+        return "";
+
+    if (!TBWidget::hovered_widget)
+        return "";
+
+    TBSelectList* select = (TBSelectList*) widget_;
+
+    if (!select->IsAncestorOf(TBWidget::hovered_widget))
+    {
+        return "";
+    }
+
+    String id_;
+    GetSubsystem<UI>()->GetTBIDString(TBWidget::hovered_widget->GetID(), id_);
+
+    return id_;
+
+}
+
 void UISelectList::SetSource(UISelectItemSource* source)
 {
     if (!widget_)

+ 1 - 0
Source/Atomic/UI/UISelectList.h

@@ -29,6 +29,7 @@ public:
     void SetValue(int value);
     int GetValue();
 
+    String GetHoverItemID();
     String GetSelectedItemID();
 
     tb::TBSelectList* GetTBSelectList();

+ 3 - 0
Source/AtomicEditorWork/Editors/SceneEditor3D/SceneView3D.cpp

@@ -366,6 +366,9 @@ void SceneView3D::HandleDragEnded(StringHash eventType, VariantMap& eventData)
 
     Object* object = dragObject->GetObject();
 
+    if (!object)
+        return;
+
     if (object->GetType() == Asset::GetTypeStatic())
     {
         Asset* asset = (Asset*) object;

+ 7 - 7
Source/ToolCore/Assets/AssetDatabase.cpp

@@ -112,6 +112,7 @@ Asset* AssetDatabase::GetAssetByPath(const String& path)
 
 void AssetDatabase::Scan()
 {
+
     FileSystem* fs = GetSubsystem<FileSystem>();
     const String& resourcePath = project_->GetResourcePath();
 
@@ -148,8 +149,6 @@ void AssetDatabase::Scan()
 
     for (unsigned i = 0; i < importResults.Size(); i++)
     {
-        //Import(importResults[i]);
-
         const String& path = importResults[i];
 
         String md5 = GeneratePathGUID(path);
@@ -157,11 +156,12 @@ void AssetDatabase::Scan()
         // get the current time stamp
         unsigned ctimestamp = fs->GetLastModifiedTime(path);
 
-        SharedPtr<Asset> asset(new Asset(context_, md5, ctimestamp));
-        assets_.Push(asset);
-
-        asset->SetPath(path);
-
+        if (!GetAssetByPath(path))
+        {
+            SharedPtr<Asset> asset(new Asset(context_, md5, ctimestamp));
+            assets_.Push(asset);
+            asset->SetPath(path);
+        }
     }
 
     PODVector<Asset*> dirty;