Sfoglia il codice sorgente

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

Marko Pintera 12 anni fa
parent
commit
10103490e2

+ 0 - 5
BansheeEngine/Source/BsEngineGUI.cpp

@@ -111,9 +111,6 @@ namespace BansheeEngine
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 
 		// 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;
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
@@ -298,8 +295,6 @@ namespace BansheeEngine
 		mSkin.setStyle("ListBox", dropDownListStyle);
 
 		// DropDown scroll up button arrow
-		HTexture dropDownBtnScrollUpArrow = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + DropDownBoxBtnUpArrowTex));
-
 		GUIElementStyle dropDownScrollUpBtnArrowStyle;
 		dropDownScrollUpBtnArrowStyle.normal.texture = getTexture(DropDownBoxBtnUpArrowTex);
 		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 TreeViewExpandButtonOffNormal;
+		static const CM::String TreeViewExpandButtonOffHover;
+		static const CM::String TreeViewExpandButtonOnNormal;
+		static const CM::String TreeViewExpandButtonOnHover;
+
 		static BS::HSpriteTexture getTexture(const CM::String& name);
 	};
 }

+ 2 - 1
CamelotClient/Include/BsGUISceneTreeView.h

@@ -16,7 +16,7 @@ namespace BansheeEditor
 			TreeElement* mParent;
 			CM::Vector<TreeElement*>::type mChildren;
 
-			BS::GUIButton* mFoldoutBtn;
+			BS::GUIToggle* mFoldoutBtn;
 			BS::GUILabel* mElement;
 
 			CM::HSceneObject mSceneObject;
@@ -68,5 +68,6 @@ namespace BansheeEditor
 			BS::GUIElementStyle* foldoutBtnStyle, const BS::GUILayoutOptions& layoutOptions);
 
 		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::TreeViewExpandButtonOffNormal = "TreeViewExpandButtonOffNormal.psd";
+	const String EditorGUI::TreeViewExpandButtonOffHover = "TreeViewExpandButtonOffHover.psd";
+	const String EditorGUI::TreeViewExpandButtonOnNormal = "TreeViewExpandButtonOnNormal.psd";
+	const String EditorGUI::TreeViewExpandButtonOnHover = "TreeViewExpandButtonOnHover.psd";
+
 	EditorGUI::EditorGUI()
 	{
 		// TODO - Normally I want to load this from some file
@@ -140,9 +145,6 @@ namespace BansheeEditor
 		mSkin.setStyle(GUILabel::getGUITypeName(), labelStyle);
 
 		// 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;
 		windowFrameStyle.normal.texture = getTexture(WindowFrameNormal);
 		windowFrameStyle.focused.texture = getTexture(WindowFrameFocused);
@@ -154,9 +156,6 @@ namespace BansheeEditor
 		mSkin.setStyle("WindowFrame", windowFrameStyle);
 
 		// 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;
 		buttonStyle.normal.texture = getTexture(ButtonNormalTex);
 		buttonStyle.hover.texture = getTexture(ButtonHoverTex);
@@ -631,6 +630,36 @@ namespace BansheeEditor
 		dockSliderBtnStyle.width = 2;
 
 		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)

+ 72 - 19
CamelotClient/Source/BsGUISceneTreeView.cpp

@@ -6,6 +6,7 @@
 #include "BsGUILabel.h"
 #include "BsGUISpace.h"
 #include "BsGUIWidget.h"
+#include "BsGUIToggle.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUISkin.h"
 #include "CmSceneObject.h"
@@ -18,7 +19,7 @@ namespace BansheeEditor
 {
 	const UINT32 GUISceneTreeView::ELEMENT_EXTRA_SPACING = 3;
 	const UINT32 GUISceneTreeView::INDENT_SIZE = 10;
-	const UINT32 GUISceneTreeView::INITIAL_INDENT_OFFSET = 10;
+	const UINT32 GUISceneTreeView::INITIAL_INDENT_OFFSET = 16;
 
 	GUISceneTreeView::TreeElement::TreeElement()
 		:mParent(nullptr), mFoldoutBtn(nullptr), mElement(nullptr),
@@ -97,6 +98,7 @@ namespace BansheeEditor
 		mRootElement.mSceneObject = root;
 		mRootElement.mId = root->getId();
 		mRootElement.mSortedIdx = 0;
+		mRootElement.mIsExpanded = true;
 
 		Stack<UpdateTreeElement>::type todo;
 		todo.push(UpdateTreeElement(&mRootElement, 0, true));
@@ -195,13 +197,16 @@ namespace BansheeEditor
 				{
 					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)
 						{
-							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;
 			}
 			
-			if(current->mIsDirty)
+			if(current->mIsDirty && current != &mRootElement)
 			{
 				if(updateElement.visible)
 				{
 					if(current->mElement == nullptr)
 					{
 						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
 				{
-					// TODO - If either label or expand button exist remove them
 					if(current->mElement != nullptr)
 					{
 						GUIElement::destroy(current->mElement);
 						current->mElement = nullptr;
 					}
+
+					if(current->mFoldoutBtn != nullptr)
+					{
+						GUIElement::destroy(current->mFoldoutBtn);
+						current->mFoldoutBtn = nullptr;
+					}
 				}
 
 				markContentAsDirty();
@@ -248,7 +271,7 @@ namespace BansheeEditor
 			{
 				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;
 	}
 
+	void GUISceneTreeView::elementToggled(TreeElement* element, bool toggled)
+	{
+		element->mIsExpanded = toggled;
+	}
+
 	Vector2I GUISceneTreeView::_getOptimalSize() const
 	{
 		struct UpdateTreeElement
@@ -296,7 +324,7 @@ namespace BansheeEditor
 					Vector2I curOptimalSize = current->mElement->_getOptimalSize();
 					optimalSize.x = std::max(optimalSize.x, 
 						(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)
@@ -310,10 +338,10 @@ namespace BansheeEditor
 			else
 			{
 				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)
-					optimalSize.x = std::min((INT32)_getLayoutOptions().maxWidth, optimalSize.y);
+					optimalSize.x = std::min((INT32)_getLayoutOptions().maxWidth, optimalSize.x);
 			}
 
 			if(_getLayoutOptions().fixedHeight)
@@ -356,6 +384,8 @@ namespace BansheeEditor
 		// 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()?)
 
+		Vector<TreeElement*>::type tempOrderedElements;
+
 		Vector2I offset(x, y);
 		while(!todo.empty())
 		{
@@ -364,11 +394,18 @@ namespace BansheeEditor
 			UINT32 indent = currentUpdateElement.indent;
 			todo.pop();
 
+			tempOrderedElements.resize(current->mChildren.size(), nullptr);
 			for(auto& child : current->mChildren)
+			{
+				tempOrderedElements[child->mSortedIdx] = child;
+			}
+
+			for(auto& child : tempOrderedElements)
 			{
 				if(!child->mIsVisible)
 					continue;
 
+				INT32 yOffset = 0;
 				if(child->mElement != nullptr)
 				{
 					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);
 					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));
 			}
 		}

+ 5 - 1
CamelotClient/Source/CmTestTextSprite.cpp

@@ -48,7 +48,11 @@ namespace BansheeEditor
 		GUIArea* area = GUIArea::createStretchedXY(*this, 0, 0, 0, 0);
 
 		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))));
 		//mLabel = GUILabel::create(*this, HString(L""));