Marko Pintera 12 лет назад
Родитель
Сommit
6d25e564d2

+ 20 - 0
CamelotClient/Include/BsGUIResourceTreeView.h

@@ -51,11 +51,22 @@ namespace BansheeEditor
 	protected:
 		InternalDraggedResources* mDraggedResources;
 		ResourceTreeElement mRootElement;
+		CM::RenderWindow* mCurrentWindow;
+		CM::OSDropTarget* mDropTarget;
+		bool mDropTargetDragActive;
+
+		boost::signals::connection mDropTargetEnterConn;
+		boost::signals::connection mDropTargetMoveConn;
+		boost::signals::connection mDropTargetLeaveConn;
+		boost::signals::connection mDropTargetDroppedConn;
 
 		GUIResourceTreeView(BS::GUIWidget& parent, BS::GUIElementStyle* backgroundStyle, BS::GUIElementStyle* elementBtnStyle, 
 			BS::GUIElementStyle* foldoutBtnStyle, BS::GUIElementStyle* selectionBackgroundStyle, BS::GUIElementStyle* editBoxStyle, 
 			BS::GUIElementStyle* dragHighlightStyle, BS::GUIElementStyle* dragSepHighlightStyle, const BS::GUILayoutOptions& layoutOptions);
 
+		virtual void _updateLayoutInternal(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
+			CM::RectI clipRect, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
+
 		virtual TreeElement& getRootElement() { return mRootElement; }
 		virtual const TreeElement& getRootElementConst() const { return mRootElement; }
 		virtual void updateTreeElementHierarchy();
@@ -74,8 +85,17 @@ namespace BansheeEditor
 		void entryAdded(const CM::WPath& path);
 		void entryRemoved(const CM::WPath& path);
 
+		void setDropTarget(CM::RenderWindow* parentWindow, CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height);
+		void clearDropTarget();
+
+		void dropTargetDragMove(CM::INT32 x, CM::INT32 y);
+		void dropTargetDragLeave();
+		void dropTargetDragDropped(CM::INT32 x, CM::INT32 y);
+
 		void quicksortTreeElements(CM::Vector<TreeElement*>::type& elements, CM::INT32 first, CM::INT32 last);
 
 		CM::WPath findUniquePath(const CM::WPath& path);
+
+		void _changeParentWidget(BS::GUIWidget* widget);
 	};
 }

+ 1 - 1
CamelotClient/Include/BsGUITreeView.h

@@ -76,7 +76,7 @@ namespace BansheeEditor
 		CM::Vector2I _getOptimalSize() const;
 		void updateClippedBounds();
 
-		void _updateLayoutInternal(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
+		virtual void _updateLayoutInternal(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height,
 			CM::RectI clipRect, CM::UINT8 widgetDepth, CM::UINT16 areaDepth);
 	protected:
 		static const CM::UINT32 ELEMENT_EXTRA_SPACING;

+ 133 - 4
CamelotClient/Source/BsGUIResourceTreeView.cpp

@@ -6,6 +6,10 @@
 #include "CmResourceManifest.h"
 #include "BsProjectLibrary.h"
 #include "CmFileSystem.h"
+#include "BsGUIWidget.h"
+#include "CmViewport.h"
+#include "CmRenderWindow.h"
+#include "CmPlatform.h"
 
 using namespace CamelotFramework;
 using namespace BansheeEngine;
@@ -28,7 +32,7 @@ namespace BansheeEditor
 		GUIElementStyle* foldoutBtnStyle, GUIElementStyle* selectionBackgroundStyle, GUIElementStyle* editBoxStyle, 
 		BS::GUIElementStyle* dragHighlightStyle, BS::GUIElementStyle* dragSepHighlightStyle, const GUILayoutOptions& layoutOptions)
 		:GUITreeView(parent, backgroundStyle, elementBtnStyle, foldoutBtnStyle, selectionBackgroundStyle, editBoxStyle, dragHighlightStyle,
-		dragSepHighlightStyle, layoutOptions), mDraggedResources(nullptr)
+		dragSepHighlightStyle, layoutOptions), mDraggedResources(nullptr), mCurrentWindow(nullptr), mDropTarget(nullptr), mDropTargetDragActive(false)
 	{
 		struct StackElem
 		{
@@ -67,11 +71,19 @@ namespace BansheeEditor
 
 			sortTreeElement(curElem.treeElem);
 		}
+
+		
+
+		if(parent.getTarget()->getTarget()->isWindow())
+		{
+			RenderWindow* parentWindow = static_cast<RenderWindow*>(parent.getTarget()->getTarget().get());
+			setDropTarget(parentWindow, _getOffset().x, _getOffset().y, _getWidth(), _getHeight());
+		}
 	}
 
 	GUIResourceTreeView::~GUIResourceTreeView()
 	{
-
+		clearDropTarget();
 	}
 
 	GUIResourceTreeView* GUIResourceTreeView::create(GUIWidget& parent, GUIElementStyle* backgroundStyle, GUIElementStyle* elementBtnStyle, 
@@ -90,6 +102,16 @@ namespace BansheeEditor
 			foldoutBtnStyle, selectionBackgroundStyle, editBoxStyle, dragHighlightStyle, dragSepHighlightStyle, GUILayoutOptions::create(options, &GUISkin::DefaultStyle));
 	}
 
+	void GUIResourceTreeView::_updateLayoutInternal(INT32 x, INT32 y, UINT32 width, UINT32 height, RectI clipRect, UINT8 widgetDepth, UINT16 areaDepth)
+	{
+		GUITreeView::_updateLayoutInternal(x, y, width, height, clipRect, widgetDepth, areaDepth);
+
+		if(mDropTarget != nullptr)
+		{
+			mDropTarget->setArea(x, y, width, height);
+		}
+	}
+
 	void GUIResourceTreeView::updateTreeElementHierarchy()
 	{
 		// Do nothing, updates are handled via callbacks
@@ -241,6 +263,99 @@ namespace BansheeEditor
 			deleteTreeElement(treeElement);
 	}
 
+	void GUIResourceTreeView::setDropTarget(CM::RenderWindow* parentWindow, CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height)
+	{
+		if(mDropTarget != nullptr)
+		{
+			Platform::destroyDropTarget(*mDropTarget);
+
+			mDropTargetEnterConn.disconnect();
+			mDropTargetLeaveConn.disconnect();
+			mDropTargetMoveConn.disconnect();
+			mDropTargetDroppedConn.disconnect();
+		}
+
+		if(parentWindow != nullptr)
+		{
+			mCurrentWindow = parentWindow;
+			mDropTarget = &Platform::createDropTarget(mCurrentWindow, _getOffset().x, _getOffset().y, _getWidth(), _getHeight());
+
+			mDropTargetEnterConn = mDropTarget->onEnter.connect(boost::bind(&GUIResourceTreeView::dropTargetDragMove, this, _1, _2));
+			mDropTargetMoveConn = mDropTarget->onDragOver.connect(boost::bind(&GUIResourceTreeView::dropTargetDragMove, this, _1, _2));
+			mDropTargetLeaveConn = mDropTarget->onLeave.connect(boost::bind(&GUIResourceTreeView::dropTargetDragLeave, this));
+			mDropTargetDroppedConn = mDropTarget->onDrop.connect(boost::bind(&GUIResourceTreeView::dropTargetDragDropped, this, _1, _2));
+		}
+		else
+			mDropTarget = nullptr;
+	}
+
+	void GUIResourceTreeView::clearDropTarget()
+	{
+		setDropTarget(nullptr, 0, 0, 0, 0);
+	}
+
+	void GUIResourceTreeView::dropTargetDragMove(CM::INT32 x, CM::INT32 y)
+	{
+		mDragPosition = Vector2I(x, y);
+		mDragInProgress = true;
+		mDropTargetDragActive = true;
+		markContentAsDirty();
+
+		if(mBottomScrollBounds.contains(mDragPosition))
+		{
+			if(mScrollState != ScrollState::Down)
+				mScrollState = ScrollState::TransitioningDown;
+		}
+		else if(mTopScrollBounds.contains(mDragPosition))
+		{
+			if(mScrollState != ScrollState::Up)
+				mScrollState = ScrollState::TransitioningUp;
+		}
+		else
+			mScrollState = ScrollState::None;
+	}
+
+	void GUIResourceTreeView::dropTargetDragLeave()
+	{
+		mDragInProgress = false;
+		mDropTargetDragActive = false;
+		markContentAsDirty();
+	}
+
+	void GUIResourceTreeView::dropTargetDragDropped(CM::INT32 x, CM::INT32 y)
+	{
+		const GUITreeView::InteractableElement* element = findElementUnderCoord(Vector2I(x, y));
+
+		TreeElement* treeElement = nullptr;
+		if(element != nullptr)
+		{
+			if(element->isTreeElement())
+				treeElement = element->getTreeElement();
+			else
+				treeElement = element->parent;
+		}
+
+		if(mDropTarget->getDropType() == OSDropType::FileList)
+		{
+			Vector<WString>::type fileList = mDropTarget->getFileList();
+
+			mDraggedResources = cm_new<InternalDraggedResources>((UINT32)fileList.size());
+			for(UINT32 i = 0; i < (UINT32)fileList.size(); i++)
+				mDraggedResources->resourcePaths[i] = toPath(fileList[i]);
+
+			dragAndDropEnded(treeElement);
+
+			cm_delete(mDraggedResources);
+			mDraggedResources = nullptr;
+
+			unselectAll();
+		}
+
+		mDragInProgress = false;
+		mDropTargetDragActive = false;
+		markContentAsDirty();
+	}
+
 	CM::WPath GUIResourceTreeView::findUniquePath(const CM::WPath& path)
 	{
 		if(FileSystem::exists(path))
@@ -256,6 +371,8 @@ namespace BansheeEditor
 				newPath = PathUtil::combine(PathUtil::combine(noExtensionPath, toPath(L" " + toWString(cnt))), extension);
 				cnt++;
 			} while (FileSystem::exists(newPath));
+
+			return newPath;
 		}
 		else
 			return path;
@@ -263,7 +380,7 @@ namespace BansheeEditor
 
 	bool GUIResourceTreeView::acceptDragAndDrop() const
 	{
-		return DragAndDropManager::instance().isDragInProgress() && DragAndDropManager::instance().getDragTypeId() == (UINT32)DragAndDropType::Resources;
+		return mDropTargetDragActive || DragAndDropManager::instance().isDragInProgress() && DragAndDropManager::instance().getDragTypeId() == (UINT32)DragAndDropType::Resources;
 	}
 
 	void GUIResourceTreeView::dragAndDropStart()
@@ -276,7 +393,6 @@ namespace BansheeEditor
 		ResourceManifestPtr resourceManifest = gResources().getResourceManifest();
 
 		UINT32 cnt = 0;
-		UINT32 numValidResources = 0;
 		for(auto& selectedElement : mSelectedElements)
 		{
 			ResourceTreeElement* resourceTreeElement = static_cast<ResourceTreeElement*>(selectedElement.element);
@@ -328,6 +444,19 @@ namespace BansheeEditor
 		}
 	}
 
+	void GUIResourceTreeView::_changeParentWidget(GUIWidget* widget)
+	{
+		GUITreeView::_changeParentWidget(widget);
+
+		if(widget->getTarget()->getTarget()->isWindow())
+		{
+			RenderWindow* parentWindow = static_cast<RenderWindow*>(widget->getTarget()->getTarget().get());
+			setDropTarget(parentWindow, _getOffset().x, _getOffset().y, _getWidth(), _getHeight());
+		}
+		else
+			clearDropTarget();
+	}
+
 	const String& GUIResourceTreeView::getGUITypeName()
 	{
 		static String typeName = "ResourceTreeView";

+ 9 - 0
ProjectLibrary.txt

@@ -1,4 +1,13 @@
 
+Today:
+ - Fix TreeView issues with expand
+
+Tomorrow:
+ - Attempt to add ResourceTreeView to scene (and initialize ProjectLibrary)
+ - Project library save/load
+ - Figure out how to deal with import queue
+ 
+ 
  ProjectLibrary
   - Save/Load - saves/loads the hierarchy of ResourceEntries