Преглед изворни кода

TreeView now properly displays elements as sorted
Root element is expanded by default
Root element has no GUI elements

Marko Pintera пре 12 година
родитељ
комит
10103490e2

+ 0 - 5
BansheeEngine/Source/BsEngineGUI.cpp

@@ -111,9 +111,6 @@ namespace BansheeEngine
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 
 
 		// Button
 		// Button
-		HTexture buttonNormalTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + ButtonNormalTex));
-		HTexture buttonHoverTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + ButtonHoverTex));
-
 		GUIElementStyle buttonStyle;
 		GUIElementStyle buttonStyle;
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
@@ -298,8 +295,6 @@ namespace BansheeEngine
 		mSkin.setStyle("ListBox", dropDownListStyle);
 		mSkin.setStyle("ListBox", dropDownListStyle);
 
 
 		// DropDown scroll up button arrow
 		// DropDown scroll up button arrow
-		HTexture dropDownBtnScrollUpArrow = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnUpArrowTex));
-
 		GUIElementStyle dropDownScrollUpBtnArrowStyle;
 		GUIElementStyle dropDownScrollUpBtnArrowStyle;
 		dropDownScrollUpBtnArrowStyle.normal.texture = getTexture(DropDownBoxBtnUpArrowTex);
 		dropDownScrollUpBtnArrowStyle.normal.texture = getTexture(DropDownBoxBtnUpArrowTex);
 		dropDownScrollUpBtnArrowStyle.hover.texture = dropDownScrollUpBtnArrowStyle.normal.texture;
 		dropDownScrollUpBtnArrowStyle.hover.texture = dropDownScrollUpBtnArrowStyle.normal.texture;

+ 5 - 0
CamelotClient/Include/BsEditorGUI.h

@@ -103,6 +103,11 @@ namespace BansheeEditor
 
 
 		static const CM::String DockSliderNormalTex;
 		static const CM::String DockSliderNormalTex;
 
 
+		static const CM::String TreeViewExpandButtonOffNormal;
+		static const CM::String TreeViewExpandButtonOffHover;
+		static const CM::String TreeViewExpandButtonOnNormal;
+		static const CM::String TreeViewExpandButtonOnHover;
+
 		static BS::HSpriteTexture getTexture(const CM::String& name);
 		static BS::HSpriteTexture getTexture(const CM::String& name);
 	};
 	};
 }
 }

+ 2 - 1
CamelotClient/Include/BsGUISceneTreeView.h

@@ -16,7 +16,7 @@ namespace BansheeEditor
 			TreeElement* mParent;
 			TreeElement* mParent;
 			CM::Vector<TreeElement*>::type mChildren;
 			CM::Vector<TreeElement*>::type mChildren;
 
 
-			BS::GUIButton* mFoldoutBtn;
+			BS::GUIToggle* mFoldoutBtn;
 			BS::GUILabel* mElement;
 			BS::GUILabel* mElement;
 
 
 			CM::HSceneObject mSceneObject;
 			CM::HSceneObject mSceneObject;
@@ -68,5 +68,6 @@ namespace BansheeEditor
 			BS::GUIElementStyle* foldoutBtnStyle, const BS::GUILayoutOptions& layoutOptions);
 			BS::GUIElementStyle* foldoutBtnStyle, const BS::GUILayoutOptions& layoutOptions);
 
 
 		virtual bool mouseEvent(const BS::GUIMouseEvent& ev);
 		virtual bool mouseEvent(const BS::GUIMouseEvent& ev);
+		void elementToggled(TreeElement* element, bool toggled);
 	};
 	};
 }
 }

+ 35 - 6
CamelotClient/Source/BsEditorGUI.cpp

@@ -105,6 +105,11 @@ namespace BansheeEditor
 
 
 	const String EditorGUI::DockSliderNormalTex = "DockSliderBtn.psd";
 	const String EditorGUI::DockSliderNormalTex = "DockSliderBtn.psd";
 
 
+	const String EditorGUI::TreeViewExpandButtonOffNormal = "TreeViewExpandButtonOffNormal.psd";
+	const String EditorGUI::TreeViewExpandButtonOffHover = "TreeViewExpandButtonOffHover.psd";
+	const String EditorGUI::TreeViewExpandButtonOnNormal = "TreeViewExpandButtonOnNormal.psd";
+	const String EditorGUI::TreeViewExpandButtonOnHover = "TreeViewExpandButtonOnHover.psd";
+
 	EditorGUI::EditorGUI()
 	EditorGUI::EditorGUI()
 	{
 	{
 		// TODO - Normally I want to load this from some file
 		// TODO - Normally I want to load this from some file
@@ -140,9 +145,6 @@ namespace BansheeEditor
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 
 
 		// Window frame
 		// Window frame
-		HTexture windowFrameNormalTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowFrameNormal));
-		HTexture windowFrameFocusedTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowFrameFocused));
-
 		GUIElementStyle windowFrameStyle;
 		GUIElementStyle windowFrameStyle;
 		windowFrameStyle.normal.texture = getTexture(WindowFrameNormal);
 		windowFrameStyle.normal.texture = getTexture(WindowFrameNormal);
 		windowFrameStyle.focused.texture = getTexture(WindowFrameFocused);
 		windowFrameStyle.focused.texture = getTexture(WindowFrameFocused);
@@ -154,9 +156,6 @@ namespace BansheeEditor
 		mSkin.setStyle("WindowFrame", windowFrameStyle);
 		mSkin.setStyle("WindowFrame", windowFrameStyle);
 
 
 		// Button
 		// Button
-		HTexture buttonNormalTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + ButtonNormalTex));
-		HTexture buttonHoverTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + ButtonHoverTex));
-
 		GUIElementStyle buttonStyle;
 		GUIElementStyle buttonStyle;
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
@@ -631,6 +630,36 @@ namespace BansheeEditor
 		dockSliderBtnStyle.width = 2;
 		dockSliderBtnStyle.width = 2;
 
 
 		mSkin.setStyle("DockSliderBtn", dockSliderBtnStyle);
 		mSkin.setStyle("DockSliderBtn", dockSliderBtnStyle);
+
+		/************************************************************************/
+		/* 								TREE VIEW	                     		*/
+		/************************************************************************/
+
+		// Expand button
+		GUIElementStyle treeViewExpandButtonStyle;
+		treeViewExpandButtonStyle.normal.texture = getTexture(TreeViewExpandButtonOffNormal);
+		treeViewExpandButtonStyle.hover.texture = getTexture(TreeViewExpandButtonOffHover);
+		treeViewExpandButtonStyle.active.texture = treeViewExpandButtonStyle.hover.texture;
+		treeViewExpandButtonStyle.normalOn.texture = getTexture(TreeViewExpandButtonOnNormal);
+		treeViewExpandButtonStyle.hoverOn.texture = getTexture(TreeViewExpandButtonOnHover);
+		treeViewExpandButtonStyle.activeOn.texture = treeViewExpandButtonStyle.hoverOn.texture;
+		treeViewExpandButtonStyle.fixedHeight = true;
+		treeViewExpandButtonStyle.fixedWidth = true;
+		treeViewExpandButtonStyle.height = 16;
+		treeViewExpandButtonStyle.width = 16;
+
+		mSkin.setStyle("TreeViewFoldoutBtn", treeViewExpandButtonStyle);
+
+		// Entry
+		GUIElementStyle treeViewEntryStyle;
+		treeViewEntryStyle.font = font;
+		treeViewEntryStyle.fontSize = DefaultFontSize;
+		treeViewEntryStyle.fixedWidth = false;
+		treeViewEntryStyle.fixedHeight = true;
+		treeViewEntryStyle.height = 16;
+		treeViewEntryStyle.minWidth = 10;
+
+		mSkin.setStyle("TreeViewElementBtn", treeViewEntryStyle);
 	}
 	}
 
 
 	HSpriteTexture EditorGUI::getTexture(const CM::String& name)
 	HSpriteTexture EditorGUI::getTexture(const CM::String& name)

+ 72 - 19
CamelotClient/Source/BsGUISceneTreeView.cpp

@@ -6,6 +6,7 @@
 #include "BsGUILabel.h"
 #include "BsGUILabel.h"
 #include "BsGUISpace.h"
 #include "BsGUISpace.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
+#include "BsGUIToggle.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "CmSceneObject.h"
 #include "CmSceneObject.h"
@@ -18,7 +19,7 @@ namespace BansheeEditor
 {
 {
 	const UINT32 GUISceneTreeView::ELEMENT_EXTRA_SPACING = 3;
 	const UINT32 GUISceneTreeView::ELEMENT_EXTRA_SPACING = 3;
 	const UINT32 GUISceneTreeView::INDENT_SIZE = 10;
 	const UINT32 GUISceneTreeView::INDENT_SIZE = 10;
-	const UINT32 GUISceneTreeView::INITIAL_INDENT_OFFSET = 10;
+	const UINT32 GUISceneTreeView::INITIAL_INDENT_OFFSET = 16;
 
 
 	GUISceneTreeView::TreeElement::TreeElement()
 	GUISceneTreeView::TreeElement::TreeElement()
 		:mParent(nullptr), mFoldoutBtn(nullptr), mElement(nullptr),
 		:mParent(nullptr), mFoldoutBtn(nullptr), mElement(nullptr),
@@ -97,6 +98,7 @@ namespace BansheeEditor
 		mRootElement.mSceneObject = root;
 		mRootElement.mSceneObject = root;
 		mRootElement.mId = root->getId();
 		mRootElement.mId = root->getId();
 		mRootElement.mSortedIdx = 0;
 		mRootElement.mSortedIdx = 0;
+		mRootElement.mIsExpanded = true;
 
 
 		Stack<UpdateTreeElement>::type todo;
 		Stack<UpdateTreeElement>::type todo;
 		todo.push(UpdateTreeElement(&mRootElement, 0, true));
 		todo.push(UpdateTreeElement(&mRootElement, 0, true));
@@ -195,13 +197,16 @@ namespace BansheeEditor
 				{
 				{
 					for(UINT32 i = 0; i < (UINT32)parent->mChildren.size(); i++)
 					for(UINT32 i = 0; i < (UINT32)parent->mChildren.size(); i++)
 					{
 					{
-						if(current->mSortedIdx <= parent->mChildren[i]->mSortedIdx)
-							continue;
-
-						UINT32 stringCompare = current->mName.compare(parent->mChildren[i]->mName);
+						INT32 stringCompare = current->mName.compare(parent->mChildren[i]->mName);
 						if(stringCompare > 0)
 						if(stringCompare > 0)
 						{
 						{
-							std::swap(current->mSortedIdx, parent->mChildren[i]->mSortedIdx);
+							if(current->mSortedIdx < parent->mChildren[i]->mSortedIdx)
+								std::swap(current->mSortedIdx, parent->mChildren[i]->mSortedIdx);
+						}
+						else if(stringCompare < 0)
+						{
+							if(current->mSortedIdx > parent->mChildren[i]->mSortedIdx)
+								std::swap(current->mSortedIdx, parent->mChildren[i]->mSortedIdx);
 						}
 						}
 					}
 					}
 				}
 				}
@@ -215,28 +220,46 @@ namespace BansheeEditor
 				current->mIsDirty = true;
 				current->mIsDirty = true;
 			}
 			}
 			
 			
-			if(current->mIsDirty)
+			if(current->mIsDirty && current != &mRootElement)
 			{
 			{
 				if(updateElement.visible)
 				if(updateElement.visible)
 				{
 				{
 					if(current->mElement == nullptr)
 					if(current->mElement == nullptr)
 					{
 					{
 						HString name(toWString(current->mName));
 						HString name(toWString(current->mName));
-						current->mElement = GUILabel::create(_getParentWidget(), name);
+						current->mElement = GUILabel::create(_getParentWidget(), name, mElementBtnStyle);
 					}
 					}
 
 
-					// TODO - If no label exists create it
-					// TODO - If has children and no expand button exists create it
-					// TODO - If it has no children but an expand button exists remove it
+					if(current->mChildren.size() > 0)
+					{
+						if(current->mFoldoutBtn == nullptr)
+						{
+							current->mFoldoutBtn = GUIToggle::create(_getParentWidget(), GUIContent(HString(L"")), mFoldoutBtnStyle);
+							current->mFoldoutBtn->onToggled.connect(boost::bind(&GUISceneTreeView::elementToggled, this, current, _1));
+						}
+					}
+					else
+					{
+						if(current->mFoldoutBtn != nullptr)
+						{
+							GUIElement::destroy(current->mFoldoutBtn);
+							current->mFoldoutBtn = nullptr;
+						}
+					}
 				}
 				}
 				else
 				else
 				{
 				{
-					// TODO - If either label or expand button exist remove them
 					if(current->mElement != nullptr)
 					if(current->mElement != nullptr)
 					{
 					{
 						GUIElement::destroy(current->mElement);
 						GUIElement::destroy(current->mElement);
 						current->mElement = nullptr;
 						current->mElement = nullptr;
 					}
 					}
+
+					if(current->mFoldoutBtn != nullptr)
+					{
+						GUIElement::destroy(current->mFoldoutBtn);
+						current->mFoldoutBtn = nullptr;
+					}
 				}
 				}
 
 
 				markContentAsDirty();
 				markContentAsDirty();
@@ -248,7 +271,7 @@ namespace BansheeEditor
 			{
 			{
 				for(UINT32 i = 0; i < (UINT32)current->mChildren.size(); i++)
 				for(UINT32 i = 0; i < (UINT32)current->mChildren.size(); i++)
 				{
 				{
-					todo.push(UpdateTreeElement(current->mChildren[i], i, current->mIsVisible /*&& current->mIsExpanded*/)); // TODO - Not checking for mIsExpanded atm
+					todo.push(UpdateTreeElement(current->mChildren[i], i, current->mIsVisible && current->mIsExpanded));
 				}
 				}
 			}
 			}
 		}
 		}
@@ -261,6 +284,11 @@ namespace BansheeEditor
 		return false;
 		return false;
 	}
 	}
 
 
+	void GUISceneTreeView::elementToggled(TreeElement* element, bool toggled)
+	{
+		element->mIsExpanded = toggled;
+	}
+
 	Vector2I GUISceneTreeView::_getOptimalSize() const
 	Vector2I GUISceneTreeView::_getOptimalSize() const
 	{
 	{
 		struct UpdateTreeElement
 		struct UpdateTreeElement
@@ -296,7 +324,7 @@ namespace BansheeEditor
 					Vector2I curOptimalSize = current->mElement->_getOptimalSize();
 					Vector2I curOptimalSize = current->mElement->_getOptimalSize();
 					optimalSize.x = std::max(optimalSize.x, 
 					optimalSize.x = std::max(optimalSize.x, 
 						(INT32)(INITIAL_INDENT_OFFSET + curOptimalSize.x + currentUpdateElement.indent * INDENT_SIZE));
 						(INT32)(INITIAL_INDENT_OFFSET + curOptimalSize.x + currentUpdateElement.indent * INDENT_SIZE));
-					optimalSize.y += optimalSize.y + ELEMENT_EXTRA_SPACING;
+					optimalSize.y += curOptimalSize.y + ELEMENT_EXTRA_SPACING;
 				}
 				}
 
 
 				for(auto& child : current->mChildren)
 				for(auto& child : current->mChildren)
@@ -310,10 +338,10 @@ namespace BansheeEditor
 			else
 			else
 			{
 			{
 				if(_getLayoutOptions().minWidth > 0)
 				if(_getLayoutOptions().minWidth > 0)
-					optimalSize.x = std::max((INT32)_getLayoutOptions().minWidth, optimalSize.y);
+					optimalSize.x = std::max((INT32)_getLayoutOptions().minWidth, optimalSize.x);
 
 
 				if(_getLayoutOptions().maxWidth > 0)
 				if(_getLayoutOptions().maxWidth > 0)
-					optimalSize.x = std::min((INT32)_getLayoutOptions().maxWidth, optimalSize.y);
+					optimalSize.x = std::min((INT32)_getLayoutOptions().maxWidth, optimalSize.x);
 			}
 			}
 
 
 			if(_getLayoutOptions().fixedHeight)
 			if(_getLayoutOptions().fixedHeight)
@@ -356,6 +384,8 @@ namespace BansheeEditor
 		// NOTE - Instead of iterating through all elements, try to find those within the clip rect
 		// NOTE - Instead of iterating through all elements, try to find those within the clip rect
 		// and only iterate through those. Others should somehow be marked in-active (similar to GUIElement::isDisabled()?)
 		// and only iterate through those. Others should somehow be marked in-active (similar to GUIElement::isDisabled()?)
 
 
+		Vector<TreeElement*>::type tempOrderedElements;
+
 		Vector2I offset(x, y);
 		Vector2I offset(x, y);
 		while(!todo.empty())
 		while(!todo.empty())
 		{
 		{
@@ -364,11 +394,18 @@ namespace BansheeEditor
 			UINT32 indent = currentUpdateElement.indent;
 			UINT32 indent = currentUpdateElement.indent;
 			todo.pop();
 			todo.pop();
 
 
+			tempOrderedElements.resize(current->mChildren.size(), nullptr);
 			for(auto& child : current->mChildren)
 			for(auto& child : current->mChildren)
+			{
+				tempOrderedElements[child->mSortedIdx] = child;
+			}
+
+			for(auto& child : tempOrderedElements)
 			{
 			{
 				if(!child->mIsVisible)
 				if(!child->mIsVisible)
 					continue;
 					continue;
 
 
+				INT32 yOffset = 0;
 				if(child->mElement != nullptr)
 				if(child->mElement != nullptr)
 				{
 				{
 					Vector2I elementSize = child->mElement->_getOptimalSize();
 					Vector2I elementSize = child->mElement->_getOptimalSize();
@@ -384,11 +421,27 @@ namespace BansheeEditor
 					RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
 					RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
 					child->mElement->_setClipRect(elemClipRect);
 					child->mElement->_setClipRect(elemClipRect);
 
 
-					offset.y += elementSize.y + ELEMENT_EXTRA_SPACING;
+					yOffset = elementSize.y + ELEMENT_EXTRA_SPACING;
 				}
 				}
 
 
-				// TODO - Position expand buttons
-				
+				if(child->mFoldoutBtn != nullptr)
+				{
+					Vector2I elementSize = child->mFoldoutBtn->_getOptimalSize();
+
+					offset.x -= std::min((INT32)INITIAL_INDENT_OFFSET, elementSize.y);
+
+					child->mFoldoutBtn->_setOffset(offset);
+					child->mFoldoutBtn->_setWidth(elementSize.x);
+					child->mFoldoutBtn->_setHeight(elementSize.y);
+					child->mFoldoutBtn->_setAreaDepth(areaDepth);
+					child->mFoldoutBtn->_setWidgetDepth(widgetDepth);
+
+					RectI elemClipRect(clipRect.x - offset.x, clipRect.y - offset.y, clipRect.width, clipRect.height);
+					child->mFoldoutBtn->_setClipRect(elemClipRect);
+				}
+
+				offset.y += yOffset;
+
 				todo.push(UpdateTreeElement(child, indent + 1));
 				todo.push(UpdateTreeElement(child, indent + 1));
 			}
 			}
 		}
 		}

+ 5 - 1
CamelotClient/Source/CmTestTextSprite.cpp

@@ -48,7 +48,11 @@ namespace BansheeEditor
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);
 
 
 		mSceneTreeView = GUISceneTreeView::create(*this, GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
 		mSceneTreeView = GUISceneTreeView::create(*this, GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()));
-		area->getLayout().addElement(mSceneTreeView);
+
+		GUILayout& sceneTreeViewLayout = area->getLayout().addLayoutY();
+		sceneTreeViewLayout.addFlexibleSpace();
+		sceneTreeViewLayout.addElement(mSceneTreeView);
+		sceneTreeViewLayout.addFlexibleSpace();
 
 
 		//area->getLayout().addElement(GUIRenderTexture::create(*this, sceneView, GUIOptions(GUIOption::fixedWidth(800), GUIOption::fixedHeight(600))));
 		//area->getLayout().addElement(GUIRenderTexture::create(*this, sceneView, GUIOptions(GUIOption::fixedWidth(800), GUIOption::fixedHeight(600))));
 		//mLabel = GUILabel::create(*this, HString(L""));
 		//mLabel = GUILabel::create(*this, HString(L""));