Sfoglia il codice sorgente

Various ProjectWindow fixes, mostly relating to drag and drop functionality

Marko Pintera 10 anni fa
parent
commit
7798f0d4a7

+ 10 - 2
BansheeCore/Include/Win32/BsWin32DropTarget.h

@@ -329,8 +329,16 @@ namespace BansheeEngine
 
 				if(op.type == DropOpType::Leave || op.type == DropOpType::Drop)
 				{
-					bs_delete(op.mFileList);
-					mFileLists.erase(mFileLists.begin());
+					while (!mFileLists.empty())
+					{
+						bool done = mFileLists[0] == op.mFileList;
+
+						bs_delete(mFileLists[0]);
+						mFileLists.erase(mFileLists.begin());
+
+						if (done)
+							break;
+					}
 				}
 			}
 

+ 2 - 0
BansheeEditor/Include/BsEditorWidget.h

@@ -3,6 +3,7 @@
 #include "BsEditorPrerequisites.h"
 #include "BsEditorWidgetManager.h"
 #include "BsEvent.h"
+#include "BsRect2I.h"
 
 namespace BansheeEngine
 {
@@ -16,6 +17,7 @@ namespace BansheeEngine
 		INT32 getY() const { return mY; }
 		UINT32 getWidth() const { return mWidth; }
 		UINT32 getHeight() const { return mHeight; }
+		Rect2I getBounds() const { return Rect2I(mX, mY, mWidth, mHeight); }
 		bool hasFocus() const { return mHasFocus; }
 		EditorWindowBase* getParentWindow() const;
 

+ 5 - 6
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -540,9 +540,9 @@ namespace BansheeEngine
 			if (current->type == LibraryEntryType::Directory)
 			{
 				DirectoryEntry* dirEntry = static_cast<DirectoryEntry*>(current);
+				current = nullptr;
 				for (auto& child : dirEntry->mChildren)
 				{
-					current = nullptr;
 					if (Path::comparePathElem(curElem, child->elementName))
 					{
 						idx++;
@@ -773,15 +773,11 @@ namespace BansheeEngine
 			newEntryParent = static_cast<DirectoryEntry*>(newEntryParentLib);
 		}
 
-		DirectoryEntry* newHierarchyParent = nullptr;
-		if (newEntryParent == nullptr) // New path parent doesn't exist, so we need to create the hierarchy
-			createInternalParentHierarchy(newFullPath, &newHierarchyParent, &newEntryParent);
-
 		// If the source is outside of Resources folder, just plain import the copy
 		LibraryEntry* oldEntry = findEntry(oldFullPath);
 		if (oldEntry == nullptr)
 		{
-			checkForModifications(newHierarchyParent->path);
+			checkForModifications(newFullPath);
 			return;
 		}
 
@@ -1071,6 +1067,9 @@ namespace BansheeEngine
 	{
 		Vector<Path> output;
 
+		if (entry->meta == nullptr)
+			return output;
+
 		if (entry->meta->getTypeID() == TID_Shader)
 		{
 			SPtr<ShaderMetaData> metaData = std::static_pointer_cast<ShaderMetaData>(entry->meta->getResourceMetaData());

+ 5 - 6
BansheeEngine/Include/BsGUIScrollArea.h

@@ -74,7 +74,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	GUIElementContainer::getElementType
 		 */
-		virtual ElementType _getElementType() const { return ElementType::ScrollArea; }
+		virtual ElementType _getElementType() const override { return ElementType::ScrollArea; }
 
 		/**
 		 * @brief	Returns the scroll area layout that you may use to add elements inside the scroll area.
@@ -160,7 +160,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc GUIElementContainer::updateBounds
 		 */
-		virtual void updateClippedBounds();
+		virtual void updateClippedBounds() override;
 
 		/**
 		 * @copydoc	GUIElementBase::_calculateLayoutSizeRange
@@ -178,7 +178,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	GUIElementContainer::mouseEvent
 		 */
-		virtual bool _mouseEvent(const GUIMouseEvent& ev);
+		virtual bool _mouseEvent(const GUIMouseEvent& ev) override;
 
 		/**
 		 * @brief	Called when the vertical scrollbar moves. 
@@ -197,13 +197,13 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	GUIElementContainer::_updateLayoutInternal
 		 */
-		void _updateLayoutInternal(const GUILayoutData& data);
+		void _updateLayoutInternal(const GUILayoutData& data) override;
 
 		/**
 		 * @copydoc	GUIElementContainer::_getElementAreas
 		 */
 		void _getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements, 
-			const Vector<LayoutSizeRange>& sizeRanges, const LayoutSizeRange& mySizeRange) const;
+			const Vector<LayoutSizeRange>& sizeRanges, const LayoutSizeRange& mySizeRange) const override;
 
 		/**
 		 * @copydoc	GUIElementContainer::_getElementAreas
@@ -230,6 +230,5 @@ namespace BansheeEngine
 		static const UINT32 ScrollBarWidth;
 		static const UINT32 MinHandleSize;
 		static const UINT32 WheelScrollAmount;
-
 	};
 }

+ 0 - 1
BansheeEngine/Include/BsGUIScrollBarHorz.h

@@ -2,7 +2,6 @@
 
 #include "BsPrerequisites.h"
 #include "BsGUIScrollBar.h"
-#include "BsEvent.h"
 
 namespace BansheeEngine
 {

+ 2 - 2
BansheeEngine/Source/BsDragAndDropManager.cpp

@@ -75,8 +75,6 @@ namespace BansheeEngine
 		if(!mIsDragInProgress)
 			return;
 
-		Platform::releaseMouseCapture();
-
 		if(!onDragEnded.empty())
 		{
 			DragCallbackInfo info;
@@ -86,5 +84,7 @@ namespace BansheeEngine
 		}
 		else
 			endDrag(false);
+
+		Platform::releaseMouseCapture();
 	}
 }

+ 18 - 9
BansheeEngine/Source/BsGUIScrollArea.cpp

@@ -50,7 +50,14 @@ namespace BansheeEngine
 
 	Vector2I GUIScrollArea::_getOptimalSize() const
 	{
-		return mContentLayout->_getOptimalSize();
+		Vector2I optimalSize = mContentLayout->_getOptimalSize();
+
+		// Provide 10x10 in case underlying layout is empty because
+		// 0 doesn't work well with the layout system
+		optimalSize.x = std::max(10, optimalSize.x);
+		optimalSize.y = std::max(10, optimalSize.y);
+
+		return optimalSize;
 	}
 
 	LayoutSizeRange GUIScrollArea::_calculateLayoutSizeRange() const
@@ -62,7 +69,12 @@ namespace BansheeEngine
 		// then they're not needed and the range is valid. And if it doesn't
 		// fit the area will get clipped anyway and including the scroll bars
 		// won't change the size much, but it would complicate this method significantly.
-		return mContentLayout->_calculateLayoutSizeRange();
+		LayoutSizeRange sizeRange = mContentLayout->_calculateLayoutSizeRange();
+
+		sizeRange.optimal.x = std::max(10, sizeRange.optimal.x);
+		sizeRange.optimal.y = std::max(10, sizeRange.optimal.y);
+
+		return sizeRange;
 	}
 
 	void GUIScrollArea::_getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,
@@ -251,9 +263,8 @@ namespace BansheeEngine
 			GUILayoutData vertScrollData = data;
 			vertScrollData.area = vertScrollBounds;
 
-			UINT32 clippedScrollbarWidth = std::min((UINT32)data.area.width, ScrollBarWidth);
-			vertScrollData.clipRect = Rect2I(data.clipRect.x + (vertScrollBounds.x - data.area.x), 
-				data.clipRect.y + (vertScrollBounds.y - data.area.y), clippedScrollbarWidth, data.clipRect.height);
+			vertScrollData.clipRect = vertScrollBounds;
+			vertScrollData.clipRect.clip(data.clipRect);
 
 			// This element is not a child of any layout so we treat it as a root element
 			mVertScroll->_setLayoutData(vertScrollData);
@@ -278,11 +289,9 @@ namespace BansheeEngine
 			GUILayoutData horzScrollData = data;
 			horzScrollData.area = horzScrollBounds;
 
-			UINT32 clippedScrollbarHeight = std::min((UINT32)data.area.height, ScrollBarWidth);
+			horzScrollData.clipRect = horzScrollBounds;
+			horzScrollData.clipRect.clip(data.clipRect);
 
-			// This element is not a child of any layout so we treat it as a root element
-			horzScrollData.clipRect = Rect2I(data.clipRect.x + (horzScrollBounds.x - data.area.x), 
-				data.clipRect.y + (horzScrollBounds.y - data.area.y), data.clipRect.width, clippedScrollbarHeight);
 			mHorzScroll->_setLayoutData(horzScrollData);
 			mHorzScroll->_updateLayout(horzScrollData);
 

+ 0 - 9
BansheeEngine/Source/BsGUIScrollBarHorz.cpp

@@ -1,14 +1,5 @@
 #include "BsGUIScrollBarHorz.h"
-#include "BsGUIElementStyle.h"
-#include "BsGUISkin.h"
-#include "BsGUIWidget.h"
 #include "BsGUIDimensions.h"
-#include "BsGUILayout.h"
-#include "BsGUISkin.h"
-#include "BsGUIButton.h"
-#include "BsGUISliderHandle.h"
-#include "BsGUISpace.h"
-#include "BsException.h"
 
 namespace BansheeEngine
 {

+ 0 - 9
BansheeEngine/Source/BsGUIScrollBarVert.cpp

@@ -1,14 +1,5 @@
 #include "BsGUIScrollBarVert.h"
-#include "BsGUIElementStyle.h"
-#include "BsGUISkin.h"
-#include "BsGUIWidget.h"
 #include "BsGUIDimensions.h"
-#include "BsGUILayout.h"
-#include "BsGUISkin.h"
-#include "BsGUIButton.h"
-#include "BsGUISliderHandle.h"
-#include "BsGUISpace.h"
-#include "BsException.h"
 
 namespace BansheeEngine
 {

+ 12 - 0
BansheeMono/Include/BsMonoArray.h

@@ -26,6 +26,18 @@ namespace BansheeEngine
 			mono_array_set(mInternal, T, idx, value);
 		}
 
+		template<>
+		String get(UINT32 idx);
+
+		template<>
+		WString get(UINT32 idx);
+
+		template<>
+		void set<String>(UINT32 idx, const String& value);
+
+		template<>
+		void set<WString>(UINT32 idx, const WString& value);
+
 		template<class T>
 		T* getRawPtr(UINT32 offset = 0)
 		{

+ 5 - 11
MBansheeEditor/DragDrop.cs

@@ -9,17 +9,7 @@ namespace BansheeEditor
         public static bool DragInProgress { get { return Internal_IsDragInProgress(); } }
         public static bool DropInProgress { get { return Internal_IsDropInProgress(); } }
         public static DragDropData Data { get { return Internal_GetData(); } }
-
-        public static DragDropType Type
-        {
-            get
-            {
-                if (Data != null)
-                    return Data.Type;
-
-                return DragDropType.None;
-            }
-        }
+        public static DragDropType Type { get { return Internal_GetDragType();} }
 
         public static void StartDrag(DragDropData data)
         {
@@ -38,6 +28,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern DragDropData Internal_GetData();
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern DragDropType Internal_GetDragType();
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_StartSceneObjectDrag(IntPtr instance);
 
@@ -91,6 +84,7 @@ namespace BansheeEditor
         private static extern string[] Internal_GetPaths(IntPtr thisPtr);
     }
 
+    // Note: Must match C++ enum ScriptDragDropType
     public enum DragDropType
     {
         Resource,

+ 6 - 12
MBansheeEditor/ProjectDropTarget.cs

@@ -59,14 +59,10 @@ namespace BansheeEditor
 
             if (isMouseDown && !isDragInProgress)
             {
-                Debug.Log("MOUSE DOWN");
-
                 Vector2I startWindowPos = parentWindow.ScreenToWindowPos(mouseDownScreenPos);
                 if (!Bounds.Contains(startWindowPos))
                     return;
 
-                Debug.Log("IN BOUNDS");
-
                 int distance = Vector2I.Distance(startWindowPos, currentWindowPos);
                 if (distance >= DragStartDistancePx)
                     triggerStartDrag = true;
@@ -92,8 +88,6 @@ namespace BansheeEditor
 
             if (triggerStartDrag)
             {
-                Debug.Log("TRIGGER START");
-
                 isDragInProgress = true;
                 triggerStartDrag = false;
 
@@ -133,14 +127,14 @@ namespace BansheeEditor
 
                     lastDragWindowPos = currentWindowPos;
                 }
+            }
 
-                if (DragDrop.DropInProgress)
+            if (DragDrop.DropInProgress && DragDrop.Type == DragDropType.Resource)
+            {
+                if (OnDrop != null)
                 {
-                    if (OnDrop != null)
-                    {
-                        ResourceDragDropData resourceDragDrop = (ResourceDragDropData)DragDrop.Data;
-                        OnDrop(currentWindowPos, resourceDragDrop.Paths);
-                    }
+                    ResourceDragDropData resourceDragDrop = (ResourceDragDropData)DragDrop.Data;
+                    OnDrop(currentWindowPos, resourceDragDrop.Paths);
                 }
             }
         }

+ 4 - 0
MBansheeEditor/ProjectLibrary.cs

@@ -8,6 +8,7 @@ namespace BansheeEditor
     public sealed class ProjectLibrary : ScriptObject
     {
         public static DirectoryEntry Root { get { return Internal_GetRoot(); } }
+        public static string ResourceFolder { get { return Internal_GetResourceFolder(); } }
 
         public static event Action<string> OnEntryAdded;
         public static event Action<string> OnEntryRemoved;
@@ -133,6 +134,9 @@ namespace BansheeEditor
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_Copy(string source, string destination, bool overwrite);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern string Internal_GetResourceFolder();
     }
 
     // Note: Must be the same as C++ enum ProjectLibrary::LibraryEntryType

+ 79 - 41
MBansheeEditor/ProjectWindow.cs

@@ -255,17 +255,17 @@ namespace BansheeEditor
         private const int GRID_ENTRY_SPACING = 15;
         private const int LIST_ENTRY_SPACING = 7;
         private const int MAX_LABEL_HEIGHT = 50;
-        private const int DRAG_SCROLL_HEIGHT = 50;
-        private const int DRAG_SCROLL_AMOUNT_PER_SECOND = 200;
+        private const int DRAG_SCROLL_HEIGHT = 20;
+        private const int DRAG_SCROLL_AMOUNT_PER_SECOND = 100;
         private static readonly Color PING_COLOR = Color.BansheeOrange;
         private static readonly Color SELECTION_COLOR = Color.DarkCyan;
         private static readonly Color HOVER_COLOR = new Color(Color.DarkCyan.r, Color.DarkCyan.g, Color.DarkCyan.b, 0.5f);
         private static readonly Color CUT_COLOR = new Color(1.0f, 1.0f, 1.0f, 0.5f);
 
         private bool hasContentFocus = false;
-        private bool HasContentFocus { get { return HasFocus && hasContentFocus; } } // TODO - This is dummy and never set
+        private bool HasContentFocus { get { return HasFocus && hasContentFocus; } }
 
-        private ProjectViewType viewType = ProjectViewType.Grid64;
+        private ProjectViewType viewType = ProjectViewType.Grid32;
 
         private string currentDirectory = "";
         private List<string> selectionPaths = new List<string>();
@@ -274,6 +274,7 @@ namespace BansheeEditor
 
         private GUIScrollArea contentScrollArea;
         private GUIPanel scrollAreaPanel;
+        private GUILayoutX searchBarLayout;
         private GUIButton optionsButton;
 
         private ContextMenu entryContextMenu;
@@ -281,7 +282,6 @@ namespace BansheeEditor
 
         private List<ElementEntry> entries = new List<ElementEntry>();
         private Dictionary<string, ElementEntry> entryLookup = new Dictionary<string, ElementEntry>(); 
-        private GUITexture pingUnderlay;
 
         private int autoScrollAmount;
 
@@ -308,7 +308,7 @@ namespace BansheeEditor
 
             GUILayoutY contentLayout = GUI.AddLayoutY();
 
-            GUILayoutX searchBarLayout = contentLayout.AddLayoutX();
+            searchBarLayout = contentLayout.AddLayoutX();
             GUITextField searchField = new GUITextField();
             searchField.OnChanged += OnSearchChanged;
             GUIButton clearSearchBtn = new GUIButton("C");
@@ -326,6 +326,7 @@ namespace BansheeEditor
 
             contentScrollArea = new GUIScrollArea(GUIOption.FlexibleWidth(), GUIOption.FlexibleHeight());
             contentLayout.AddElement(contentScrollArea);
+            contentLayout.AddFlexibleSpace();
 
             entryContextMenu = new ContextMenu();
             entryContextMenu.AddItem("Cut", CutSelection, new ShortcutKey(ButtonModifier.Ctrl, ButtonCode.X));
@@ -333,19 +334,19 @@ namespace BansheeEditor
             entryContextMenu.AddItem("Duplicate", DuplicateSelection, new ShortcutKey(ButtonModifier.Ctrl, ButtonCode.D));
             entryContextMenu.AddItem("Paste", PasteToSelection, new ShortcutKey(ButtonModifier.Ctrl, ButtonCode.V));
 
+            Reset();
+
             dropTarget = new ProjectDropTarget(this);
             dropTarget.Bounds = contentScrollArea.Bounds;
-            dropTarget.OnStart += DoOnDragStart; 
+            dropTarget.OnStart += DoOnDragStart;
             dropTarget.OnDrag += DoOnDragMove;
             dropTarget.OnLeave += DoOnDragLeave;
             dropTarget.OnDrop += DoOnDragDropped;
-
-            Reset();
         }
 
         private ElementEntry FindElementAt(Vector2I windowPos)
         {
-            Rect2I scrollBounds = contentScrollArea.Bounds;
+            Rect2I scrollBounds = contentScrollArea.Layout.Bounds;
             Vector2I scrollPos = windowPos;
             scrollPos.x -= scrollBounds.x;
             scrollPos.y -= scrollBounds.y;
@@ -375,27 +376,16 @@ namespace BansheeEditor
         private void DoOnDragMove(Vector2I windowPos)
         {
             ElementEntry underCursorElem = FindElementAt(windowPos);
+            
             if (underCursorElem == null)
             {
-                if (!string.IsNullOrEmpty(hoverHighlightPath))
-                {
-                    ElementEntry previousUnderCursorElem;
-                    if (entryLookup.TryGetValue(hoverHighlightPath, out previousUnderCursorElem))
-                        previousUnderCursorElem.MarkAsHovered(false);
-                }
-
-                hoverHighlightPath = "";
+                ClearHoverHighlight();
             }
             else
             {
                 if (underCursorElem.path != hoverHighlightPath)
                 {
-                    if (!string.IsNullOrEmpty(hoverHighlightPath))
-                    {
-                        ElementEntry previousUnderCursorElem;
-                        if (entryLookup.TryGetValue(hoverHighlightPath, out previousUnderCursorElem))
-                            previousUnderCursorElem.MarkAsHovered(false);
-                    }
+                    ClearHoverHighlight();
 
                     hoverHighlightPath = underCursorElem.path;
                     underCursorElem.MarkAsHovered(true);
@@ -416,40 +406,63 @@ namespace BansheeEditor
 
         private void DoOnDragLeave()
         {
-            if (!string.IsNullOrEmpty(hoverHighlightPath))
-            {
-                ElementEntry previousUnderCursorElem;
-                if (entryLookup.TryGetValue(hoverHighlightPath, out previousUnderCursorElem))
-                    previousUnderCursorElem.MarkAsHovered(false);
-            }
-
-            hoverHighlightPath = "";
+            ClearHoverHighlight();
+            autoScrollAmount = 0;
         }
 
         private void DoOnDragDropped(Vector2I windowPos, string[] paths)
         {
-            string destinationFolder = currentDirectory;
+            string resourceDir = ProjectLibrary.ResourceFolder;
+            string destinationFolder = Path.Combine(resourceDir, currentDirectory);
 
             ElementEntry underCursorElement = FindElementAt(windowPos);
             if (underCursorElement != null)
             {
                 LibraryEntry entry = ProjectLibrary.GetEntry(underCursorElement.path);
                 if (entry != null && entry.Type == LibraryEntryType.Directory)
-                    destinationFolder = entry.Path;
+                    destinationFolder = Path.Combine(resourceDir, entry.Path);
             }
 
             if (paths != null)
             {
                 foreach (var path in paths)
                 {
-                    if (PathEx.IsPartOf(destinationFolder, path) || PathEx.Compare(path, destinationFolder))
+                    if (path == null)
+                        continue;
+
+                    string absolutePath = path;
+                    if (!Path.IsPathRooted(absolutePath))
+                        absolutePath = Path.Combine(resourceDir, path);
+
+                    if (string.IsNullOrEmpty(absolutePath))
+                        continue;
+
+                    if (PathEx.IsPartOf(destinationFolder, absolutePath) || PathEx.Compare(absolutePath, destinationFolder))
                         continue;
 
-                    string destination = Path.Combine(destinationFolder, Path.GetFileName(path));
+                    string destination = Path.Combine(destinationFolder, Path.GetFileName(absolutePath));
 
-                    ProjectLibrary.Move(path, destination, true);
+                    if (ProjectLibrary.Exists(path))
+                        ProjectLibrary.Move(path, destination, true);
+                    else
+                        ProjectLibrary.Copy(path, destination, true);
                 }
             }
+
+            ClearHoverHighlight();
+            autoScrollAmount = 0;
+        }
+
+        private void ClearHoverHighlight()
+        {
+            if (!string.IsNullOrEmpty(hoverHighlightPath))
+            {
+                ElementEntry previousUnderCursorElem;
+                if (entryLookup.TryGetValue(hoverHighlightPath, out previousUnderCursorElem))
+                    previousUnderCursorElem.MarkAsHovered(false);
+            }
+
+            hoverHighlightPath = "";
         }
 
         public void Ping(Resource resource)
@@ -620,9 +633,9 @@ namespace BansheeEditor
             if (autoScrollAmount != 0)
             {
                 Rect2I contentBounds = contentScrollArea.ContentBounds;
-                float scrollPct = DRAG_SCROLL_AMOUNT_PER_SECOND / (float)contentBounds.height;
+                float scrollPct = autoScrollAmount / (float)contentBounds.height;
 
-                contentScrollArea.VerticalScroll += scrollPct;
+                contentScrollArea.VerticalScroll += scrollPct * Time.FrameDelta;
             }
 
             dropTarget.Update();
@@ -674,8 +687,6 @@ namespace BansheeEditor
 
             if (viewType == ProjectViewType.List16)
             {
-                int tileSize = 16;
-
                 for (int i = 0; i < childEntries.Length; i++)
                 {
                     ElementEntry guiEntry = new ElementEntry(contentInfo, contentInfo.main, childEntries[i]);
@@ -751,14 +762,31 @@ namespace BansheeEditor
             }
 
             Rect2I contentBounds = contentInfo.main.Bounds;
+            Rect2I minimalBounds = GetScrollAreaBounds();
+            contentBounds.width = Math.Max(contentBounds.width, minimalBounds.width);
+            contentBounds.height = Math.Max(contentBounds.height, minimalBounds.height);
+
+            Debug.Log(contentBounds + " - " + minimalBounds);
+
             GUIButton catchAll = new GUIButton("", EditorStyles.Blank);
             catchAll.Bounds = contentBounds;
             catchAll.OnClick += OnCatchAllClicked;
             catchAll.SetContextMenu(entryContextMenu);
+            catchAll.OnFocusChanged += OnContentsFocusChanged;
 
             contentInfo.underlay.AddElement(catchAll);
         }
 
+        private void OnContentsFocusChanged(bool focus)
+        {
+            if(focus)
+                Debug.Log("GOT FOCUS");
+            else
+                Debug.Log("LOST FOCUS");
+
+            hasContentFocus = focus;
+        }
+
         private void OnEntryClicked(string path)
         {
             Select(new List<string> { path });
@@ -844,6 +872,16 @@ namespace BansheeEditor
             Refresh();
         }
 
+        private Rect2I GetScrollAreaBounds()
+        {
+            Rect2I bounds = GUI.Bounds;
+            Rect2I searchBarBounds = searchBarLayout.Bounds;
+            bounds.y += searchBarBounds.height;
+            bounds.height -= searchBarBounds.height;
+
+            return bounds;
+        }
+
         protected override void WindowResized(int width, int height)
         {
             base.WindowResized(width, height);

+ 1 - 1
README.md

@@ -21,7 +21,7 @@ To compile DirectX render systems you will also need a separately installed Dire
 ## Features (currently available)
 
 * Editor
-  * Asset management & import
+  * Asset management
     * Simple drag and drop import
 	* Automatic reimport of externally modified assets
 	* Asset modifications immediately reflected in-game

+ 10 - 8
SBansheeEditor/Include/BsScriptDragDropManager.h

@@ -9,6 +9,14 @@ namespace BansheeEngine
 	class ScriptSceneObjectDragDropData;
 	class ScriptResourceDragDropData;
 
+	// Note: Must be equal to C# DragDropType enum
+	enum class ScriptDragDropType
+	{
+		Resource,
+		SceneObject,
+		None
+	};
+
 	class BS_SCR_BED_EXPORT ScriptDragDrop : public ScriptObject<ScriptDragDrop>
 	{
 	public:
@@ -23,6 +31,7 @@ namespace BansheeEngine
 		static bool internal_IsDragInProgress();
 		static bool internal_IsDropInProgress();
 		static MonoObject* internal_GetData();
+		static ScriptDragDropType internal_GetDragType();
 		static void internal_StartSceneObjectDrag(ScriptSceneObjectDragDropData* dragData);
 		static void internal_StartResourceDrag(ScriptResourceDragDropData* dragData);
 	};
@@ -63,14 +72,6 @@ namespace BansheeEngine
 		Vector<Path> mPaths;
 	};
 
-	// Note: Must be equal to C# DragDropType enum
-	enum class ScriptDragDropType
-	{
-		Resource,
-		SceneObject,
-		None
-	};
-
 	class BS_SCR_BED_EXPORT ScriptDragDropManager : public Module<ScriptDragDropManager>
 	{
 	public:
@@ -81,6 +82,7 @@ namespace BansheeEngine
 
 		bool isDropInProgress() const { return mIsDropInProgress; }
 		MonoObject* getDropData() const;
+		ScriptDragDropType getDragType() const;
 
 	private:
 		void onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo);

+ 2 - 0
SBansheeEditor/Include/BsScriptOSDropTarget.h

@@ -23,6 +23,7 @@ namespace BansheeEngine
 		HEvent mDropTargetLeaveConn;
 		HEvent mDropTargetDroppedConn;
 		HEvent mWidgetParentChangedConn;
+		HEvent mWidgetMovedConn;
 		HEvent mWidgetResizedConn;
 
 		ScriptOSDropTarget(MonoObject* instance, ScriptEditorWindow* parent);
@@ -34,6 +35,7 @@ namespace BansheeEngine
 
 		void widgetParentChanged(EditorWidgetContainer* parent);
 		void widgetResized(UINT32 width, UINT32 height);
+		void widgetMoved(INT32 x, INT32 y);
 
 		EditorWidgetBase* getParentWidget() const;
 		Rect2I getDropTargetArea() const;

+ 1 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -29,6 +29,7 @@ namespace BansheeEngine
 		static void internal_Rename(MonoString* path, MonoString* name);
 		static void internal_Move(MonoString* oldPath, MonoString* newPath, bool overwrite);
 		static void internal_Copy(MonoString* source, MonoString* destination, bool overwrite);
+		static MonoString* internal_GetResourceFolder();
 
 		static void onEntryAdded(const Path& path);
 		static void onEntryRemoved(const Path& path);

+ 23 - 0
SBansheeEditor/Source/BsScriptDragDropManager.cpp

@@ -22,6 +22,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_IsDragInProgress", &ScriptDragDrop::internal_IsDragInProgress);
 		metaData.scriptClass->addInternalCall("Internal_IsDropInProgress", &ScriptDragDrop::internal_IsDropInProgress);
 		metaData.scriptClass->addInternalCall("Internal_GetData", &ScriptDragDrop::internal_GetData);
+		metaData.scriptClass->addInternalCall("Internal_GetDragType", &ScriptDragDrop::internal_GetDragType);
 		metaData.scriptClass->addInternalCall("Internal_StartSceneObjectDrag", &ScriptDragDrop::internal_StartSceneObjectDrag);
 		metaData.scriptClass->addInternalCall("Internal_StartResourceDrag", &ScriptDragDrop::internal_StartResourceDrag);
 	}
@@ -41,6 +42,11 @@ namespace BansheeEngine
 		return ScriptDragDropManager::instance().getDropData();
 	}
 
+	ScriptDragDropType ScriptDragDrop::internal_GetDragType()
+	{
+		return ScriptDragDropManager::instance().getDragType();
+	}
+
 	void ScriptDragDrop::internal_StartSceneObjectDrag(ScriptSceneObjectDragDropData* value)
 	{
 		const Vector<HSceneObject>& sceneObjects = value->getSceneObjects();
@@ -227,6 +233,23 @@ namespace BansheeEngine
 		return nullptr;
 	}
 
+	ScriptDragDropType ScriptDragDropManager::getDragType() const
+	{
+		if (DragAndDropManager::instance().isDragInProgress())
+		{
+			UINT32 nativeType = DragAndDropManager::instance().getDragTypeId();
+
+			if (nativeType == (UINT32)DragAndDropType::SceneObject)
+				return ScriptDragDropType::SceneObject;
+			else if (nativeType == (UINT32)DragAndDropType::Resources)
+				return ScriptDragDropType::Resource;
+
+			return ScriptDragDropType::None;
+		}
+		else
+			return mDropType;
+	}
+
 	void ScriptDragDropManager::onMouseDragEnded(const PointerEvent& evt, DragCallbackInfo& callbackInfo)
 	{
 		if (!DragAndDropManager::instance().isDragInProgress())

+ 18 - 23
SBansheeEditor/Source/BsScriptOSDropTarget.cpp

@@ -31,11 +31,14 @@ namespace BansheeEngine
 		{
 			mWidgetParentChangedConn = parentWidget->onParentChanged.connect(std::bind(&ScriptOSDropTarget::widgetParentChanged, this, _1));
 			mWidgetResizedConn = parentWidget->onResized.connect(std::bind(&ScriptOSDropTarget::widgetResized, this, _1, _2));
+			mWidgetMovedConn = parentWidget->onMoved.connect(std::bind(&ScriptOSDropTarget::widgetMoved, this, _1, _2));
 
 			EditorWindowBase* parentWindow = parentWidget->getParentWindow();
 
 			if (parentWindow != nullptr)
 				setDropTarget(parentWindow->getRenderWindow(), 0, 0, 0, 0);
+
+			mParentArea = parentWidget->getBounds();
 		}
 	}
 
@@ -113,7 +116,7 @@ namespace BansheeEngine
 	{
 		EditorWidgetBase* parentWidget = nullptr;
 
-		if (mParent != nullptr && mParent->isDestroyed())
+		if (mParent != nullptr && !mParent->isDestroyed())
 			parentWidget = mParent->getEditorWidget();
 
 		return parentWidget;
@@ -122,14 +125,10 @@ namespace BansheeEngine
 	Rect2I ScriptOSDropTarget::getDropTargetArea() const
 	{
 		Rect2I dropTargetArea = mArea;
-		dropTargetArea.clip(mParentArea);
+		dropTargetArea.x += mParentArea.x;
+		dropTargetArea.y += mParentArea.y;
 
-		EditorWidgetBase* parentWidget = getParentWidget();
-		if (parentWidget != nullptr)
-		{
-			dropTargetArea.x += parentWidget->getX();
-			dropTargetArea.y += parentWidget->getY();
-		}
+		dropTargetArea.clip(mParentArea);
 
 		return dropTargetArea;
 	}
@@ -173,12 +172,8 @@ namespace BansheeEngine
 		if (thisPtr->mIsDestroyed)
 			return;
 
-		EditorWidgetBase* parentWidget = thisPtr->getParentWidget();
-		if (parentWidget == nullptr)
-			return;
-
 		MonoException* exception = nullptr;
-		onEnterThunk(thisPtr->getManagedInstance(), x - parentWidget->getX(), y - parentWidget->getY(), &exception);
+		onEnterThunk(thisPtr->getManagedInstance(), x - thisPtr->mParentArea.x, y - thisPtr->mParentArea.y, &exception);
 
 		MonoUtil::throwIfException(exception);
 	}
@@ -188,12 +183,8 @@ namespace BansheeEngine
 		if (thisPtr->mIsDestroyed)
 			return;
 
-		EditorWidgetBase* parentWidget = thisPtr->getParentWidget();
-		if (parentWidget == nullptr)
-			return;
-
 		MonoException* exception = nullptr;
-		onMoveThunk(thisPtr->getManagedInstance(), x - parentWidget->getX(), y - parentWidget->getY(), &exception);
+		onMoveThunk(thisPtr->getManagedInstance(), x - thisPtr->mParentArea.x, y - thisPtr->mParentArea.y, &exception);
 
 		MonoUtil::throwIfException(exception);
 	}
@@ -214,12 +205,8 @@ namespace BansheeEngine
 		if (thisPtr->mIsDestroyed)
 			return;
 
-		EditorWidgetBase* parentWidget = thisPtr->getParentWidget();
-		if (parentWidget == nullptr)
-			return;
-
 		MonoException* exception = nullptr;
-		onDropThunk(thisPtr->getManagedInstance(), x - parentWidget->getX(), y - parentWidget->getY(), &exception);
+		onDropThunk(thisPtr->getManagedInstance(), x - thisPtr->mParentArea.x, y - thisPtr->mParentArea.y, &exception);
 
 		MonoUtil::throwIfException(exception);
 	}
@@ -249,4 +236,12 @@ namespace BansheeEngine
 
 		setBounds(mArea);
 	}
+
+	void ScriptOSDropTarget::widgetMoved(INT32 x, INT32 y)
+	{
+		mParentArea.x = x;
+		mParentArea.y = y;
+
+		setBounds(mArea);
+	}
 }

+ 6 - 0
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -45,6 +45,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_Rename", &ScriptProjectLibrary::internal_Rename);
 		metaData.scriptClass->addInternalCall("Internal_Move", &ScriptProjectLibrary::internal_Move);
 		metaData.scriptClass->addInternalCall("Internal_Copy", &ScriptProjectLibrary::internal_Copy);
+		metaData.scriptClass->addInternalCall("Internal_GetResourceFolder", &ScriptProjectLibrary::internal_GetResourceFolder);
 
 		OnEntryAddedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryAdded", 1)->getThunk();
 		OnEntryRemovedThunk = (OnEntryChangedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnEntryRemoved", 1)->getThunk();
@@ -205,6 +206,11 @@ namespace BansheeEngine
 		ProjectLibrary::instance().copyEntry(oldPathNative, newPathNative, overwrite);
 	}
 
+	MonoString* ScriptProjectLibrary::internal_GetResourceFolder()
+	{
+		return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), ProjectLibrary::instance().getResourcesFolder().toWString());
+	}
+
 	void ScriptProjectLibrary::startUp()
 	{
 		mOnEntryAddedConn = ProjectLibrary::instance().onEntryAdded.connect(std::bind(&ScriptProjectLibrary::onEntryAdded, _1));

+ 3 - 11
TODO.txt

@@ -25,12 +25,8 @@ GUIResourceField doesn't distinguish between tex2d, tex3d and texcube.
 ----------------------------------------------------------------------
 Project window
 
-OSDropTarget works in window coordinates but EditorWindow uses editor window coordiantes for intializing it, and assumes it also returns editor window coordinates
-
-Test:
- - Drag and drop internal
- - Drag and drop from outside
- - Scroll when dragging
+TODO - When importing/reimporting stuff there should be a progress bar
+TODO - Might need to handle overwritting better when importing/moving 
 
 Simple tasks:
  - Hook up scene view drag and drop instantiation
@@ -51,7 +47,6 @@ Later:
     - While moving like this I also need to automatically scroll to the selected element
  - Hook up ping effect so it triggers when I select a resource or sceneobject
   - Add ping to SceneTreeView
- - Check if drag and drop cursor changes properly when over valid/invalid objects (might not be needed)
 
 ----------------------------------------------------------------------
 Resources
@@ -87,6 +82,7 @@ Other simple stuff:
  - Get rid of event callback from HString and figure out a better way
  - GUI TextureField similar to ResourceField but it displays the texture it has assigned
  - Better handle and gizmo shaders
+ - Splash screen
 
 ----------------------------------------------------------------------
 Handles
@@ -137,10 +133,6 @@ Issue happened when I closed the app via the X button (if that's relevant). It d
 Create a stack allocatable custom vector implementation and make getResourceDependencies and getCoreDependencies use it.
  - These methods are called often and cause allocations whenever they are.
 
-Add ProjectWindow and HierarchyWindow to C#
- - Make TreeViews a C# element?
-Set up a default layout and save it
-
 ----------------------------------------------------------------------
 Multi-resource saving
  - Modify Font so it doesn't contain a texture, but instead keeps a handle to it