瀏覽代碼

More work on getting MenuBar up and running
Unified all optimal element size calculations and fixed them to properly include element contents

Marko Pintera 12 年之前
父節點
當前提交
3cc716a4af

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -238,6 +238,7 @@
     <ClInclude Include="Include\BsGUIContent.h" />
     <ClInclude Include="Include\BsGUIContent.h" />
     <ClInclude Include="Include\BsGUIContextMenu.h" />
     <ClInclude Include="Include\BsGUIContextMenu.h" />
     <ClInclude Include="Include\BsGUIDropDownBox.h" />
     <ClInclude Include="Include\BsGUIDropDownBox.h" />
+    <ClInclude Include="Include\BsGUIHelper.h" />
     <ClInclude Include="Include\BsGUIListBox.h" />
     <ClInclude Include="Include\BsGUIListBox.h" />
     <ClInclude Include="Include\BsGUIElementBase.h" />
     <ClInclude Include="Include\BsGUIElementBase.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
     <ClInclude Include="Include\BsGUIInputTool.h" />
@@ -298,6 +299,7 @@
     <ClCompile Include="Source\BsGUIButton.cpp" />
     <ClCompile Include="Source\BsGUIButton.cpp" />
     <ClCompile Include="Source\BsGUIContent.cpp" />
     <ClCompile Include="Source\BsGUIContent.cpp" />
     <ClCompile Include="Source\BsGUIDropDownBox.cpp" />
     <ClCompile Include="Source\BsGUIDropDownBox.cpp" />
+    <ClCompile Include="Source\BsGUIHelper.cpp" />
     <ClCompile Include="Source\BsGUIListBox.cpp" />
     <ClCompile Include="Source\BsGUIListBox.cpp" />
     <ClCompile Include="Source\BsGUIElement.cpp" />
     <ClCompile Include="Source\BsGUIElement.cpp" />
     <ClCompile Include="Source\BsGUIElementBase.cpp" />
     <ClCompile Include="Source\BsGUIElementBase.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -216,6 +216,9 @@
     <ClInclude Include="Source\BsGUIContextMenu.cpp">
     <ClInclude Include="Source\BsGUIContextMenu.cpp">
       <Filter>Source Files\GUI</Filter>
       <Filter>Source Files\GUI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIHelper.h">
+      <Filter>Header Files\GUI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -371,5 +374,8 @@
     <ClCompile Include="Source\BsGUIMenu.cpp">
     <ClCompile Include="Source\BsGUIMenu.cpp">
       <Filter>Source Files\GUI</Filter>
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIHelper.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 3 - 0
BansheeEngine/Include/BsGUIButton.h

@@ -3,6 +3,7 @@
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsImageSprite.h"
 #include "BsImageSprite.h"
+#include "BsTextSprite.h"
 #include "BsGUIContent.h"
 #include "BsGUIContent.h"
 #include "boost/signal.hpp"
 #include "boost/signal.hpp"
 
 
@@ -73,5 +74,7 @@ namespace BansheeEngine
 		GUIButton(GUIWidget& parent, const GUIElementStyle* style, const GUIContent& content, const GUILayoutOptions& layoutOptions);
 		GUIButton(GUIWidget& parent, const GUIElementStyle* style, const GUIContent& content, const GUILayoutOptions& layoutOptions);
 
 
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
+
+		TEXT_SPRITE_DESC getTextDesc() const;
 	};
 	};
 }
 }

+ 15 - 0
BansheeEngine/Include/BsGUIHelper.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsTextSprite.h"
+#include "BsGUIContent.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT GUIHelper
+	{
+	public:
+		static CM::Int2 calcOptimalContentsSize(const GUIContent& content, const GUIElementStyle& style, const GUILayoutOptions& layoutOptions);
+		static CM::Int2 calcOptimalContentsSize(const CM::WString& text, const GUIElementStyle& style, const GUILayoutOptions& layoutOptions);
+	};
+}

+ 2 - 0
BansheeEngine/Include/BsGUIListBox.h

@@ -3,6 +3,7 @@
 #include "BsPrerequisites.h"
 #include "BsPrerequisites.h"
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsImageSprite.h"
 #include "BsImageSprite.h"
+#include "BsTextSprite.h"
 #include "boost/signal.hpp"
 #include "boost/signal.hpp"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -66,6 +67,7 @@ namespace BansheeEngine
 		GUIListBox(GUIWidget& parent, const GUIElementStyle* style, const CM::Vector<CM::WString>::type& elements, const GUILayoutOptions& layoutOptions);
 		GUIListBox(GUIWidget& parent, const GUIElementStyle* style, const CM::Vector<CM::WString>::type& elements, const GUILayoutOptions& layoutOptions);
 
 
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
+		TEXT_SPRITE_DESC getTextDesc() const;
 
 
 		void elementSelected(CM::UINT32 idx);
 		void elementSelected(CM::UINT32 idx);
 	};
 	};

+ 1 - 2
BansheeEngine/Include/BsGUIMenu.h

@@ -31,8 +31,7 @@ namespace BansheeEngine
 		std::function<void()> mCallback;
 		std::function<void()> mCallback;
 		CM::Vector<GUIMenuItem*>::type mChildren;
 		CM::Vector<GUIMenuItem*>::type mChildren;
 
 
-		CM::Vector<GUIMenuItem*>::type::const_iterator findChildInternal(const CM::WString& name) const;
-		CM::Vector<GUIMenuItem*>::type::iterator findChildInternal(const CM::WString& name);
+		GUIMenuItem* findChild(const CM::WString& name);
 	};
 	};
 
 
 	class BS_EXPORT GUIMenu
 	class BS_EXPORT GUIMenu

+ 3 - 0
BansheeEngine/Include/BsGUIToggle.h

@@ -4,6 +4,7 @@
 #include "BsGUIElement.h"
 #include "BsGUIElement.h"
 #include "BsGUIToggleGroup.h"
 #include "BsGUIToggleGroup.h"
 #include "BsImageSprite.h"
 #include "BsImageSprite.h"
+#include "BsTextSprite.h"
 #include "BsGUIContent.h"
 #include "BsGUIContent.h"
 #include "boost/signal.hpp"
 #include "boost/signal.hpp"
 
 
@@ -77,6 +78,8 @@ namespace BansheeEngine
 
 
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 		virtual bool mouseEvent(const GUIMouseEvent& ev);
 
 
+		TEXT_SPRITE_DESC getTextDesc() const;
+
 	private:
 	private:
 		std::shared_ptr<GUIToggleGroup> mToggleGroup;
 		std::shared_ptr<GUIToggleGroup> mToggleGroup;
 		ImageSprite* mImageSprite;
 		ImageSprite* mImageSprite;

+ 2 - 2
BansheeEngine/Source/BsEngineGUI.cpp

@@ -657,9 +657,9 @@ namespace BansheeEngine
 		menuBarBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnNormal));
 		menuBarBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnNormal));
 		menuBarBtnStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnHover));
 		menuBarBtnStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnHover));
 		menuBarBtnStyle.active.texture = menuBarBtnStyle.hover.texture;
 		menuBarBtnStyle.active.texture = menuBarBtnStyle.hover.texture;
-		menuBarBtnStyle.fixedHeight = false;
+		menuBarBtnStyle.fixedHeight = true;
 		menuBarBtnStyle.fixedWidth = false;
 		menuBarBtnStyle.fixedWidth = false;
-		menuBarBtnStyle.height = 4;
+		menuBarBtnStyle.height = 15;
 		menuBarBtnStyle.width = 4;
 		menuBarBtnStyle.width = 4;
 		menuBarBtnStyle.font = font;
 		menuBarBtnStyle.font = font;
 		menuBarBtnStyle.fontSize = DefaultFontSize;
 		menuBarBtnStyle.fontSize = DefaultFontSize;

+ 25 - 21
BansheeEngine/Source/BsGUIButton.cpp

@@ -6,6 +6,7 @@
 #include "BsTextSprite.h"
 #include "BsTextSprite.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIMouseEvent.h"
+#include "BsGUIHelper.h"
 #include "CmTexture.h"
 #include "CmTexture.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -137,19 +138,7 @@ namespace BansheeEngine
 
 
 		mImageSprite->update(mImageDesc);
 		mImageSprite->update(mImageDesc);
 
 
-		TEXT_SPRITE_DESC textDesc;
-		textDesc.text = mContent.getText();
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
-
-		Rect textBounds = getContentBounds();
-
-		textDesc.width = textBounds.width;
-		textDesc.height = textBounds.height;
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
-
-		mTextSprite->update(textDesc);
+		mTextSprite->update(getTextDesc());
 
 
 		if(mContentImageSprite != nullptr)
 		if(mContentImageSprite != nullptr)
 		{
 		{
@@ -171,22 +160,20 @@ namespace BansheeEngine
 
 
 	UINT32 GUIButton::_getOptimalWidth() const
 	UINT32 GUIButton::_getOptimalWidth() const
 	{
 	{
+		UINT32 imageWidth = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getWidth();
-		}
+			imageWidth = mImageDesc.texture->getTexture()->getWidth();
 
 
-		return 0;
+		return std::max(imageWidth, (UINT32)GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).x);
 	}
 	}
 
 
 	UINT32 GUIButton::_getOptimalHeight() const
 	UINT32 GUIButton::_getOptimalHeight() const
 	{
 	{
+		UINT32 imageHeight = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getHeight();
-		}
+			imageHeight = mImageDesc.texture->getTexture()->getHeight();
 
 
-		return 0;
+		return std::max(imageHeight, (UINT32)GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).y);
 	}
 	}
 
 
 	UINT32 GUIButton::_getRenderElementDepth(UINT32 renderElementIdx) const
 	UINT32 GUIButton::_getRenderElementDepth(UINT32 renderElementIdx) const
@@ -321,4 +308,21 @@ namespace BansheeEngine
 		
 		
 		return false;
 		return false;
 	}
 	}
+
+	TEXT_SPRITE_DESC GUIButton::getTextDesc() const
+	{
+		TEXT_SPRITE_DESC textDesc;
+		textDesc.text = mContent.getText();
+		textDesc.font = mStyle->font;
+		textDesc.fontSize = mStyle->fontSize;
+
+		Rect textBounds = getContentBounds();
+
+		textDesc.width = textBounds.width;
+		textDesc.height = textBounds.height;
+		textDesc.horzAlign = mStyle->textHorzAlign;
+		textDesc.vertAlign = mStyle->textVertAlign;
+
+		return textDesc;
+	}
 }
 }

+ 51 - 0
BansheeEngine/Source/BsGUIHelper.cpp

@@ -0,0 +1,51 @@
+#include "BsGUIHelper.h"
+#include "BsSpriteTexture.h"
+#include "BsGUIElementStyle.h"
+#include "BsGUILayoutOptions.h"
+#include "CmTexture.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	Int2 GUIHelper::calcOptimalContentsSize(const GUIContent& content, const GUIElementStyle& style, const GUILayoutOptions& layoutOptions)
+	{
+		Int2 textContentBounds = calcOptimalContentsSize(content.getText(), style, layoutOptions);
+
+		UINT32 contentWidth = style.margins.left + style.margins.right + style.contentOffset.left + style.contentOffset.right;
+		UINT32 contentHeight = style.margins.top + style.margins.bottom + style.contentOffset.top + style.contentOffset.bottom;
+		if(content.getImage() != nullptr)
+		{
+			contentWidth += content.getImage()->getTexture()->getWidth();
+			contentHeight += content.getImage()->getTexture()->getHeight();
+		}
+
+		return Int2(std::max((UINT32)textContentBounds.x, contentWidth), std::max((UINT32)textContentBounds.y, contentHeight));
+	}
+
+	CM::Int2 GUIHelper::calcOptimalContentsSize(const WString& text, const GUIElementStyle& style, const GUILayoutOptions& layoutOptions)
+	{
+		UINT32 wordWrapWidth = 0;
+
+		if(style.wordWrap)
+		{
+			if(layoutOptions.fixedWidth)
+				wordWrapWidth = layoutOptions.width;
+			else
+				wordWrapWidth = layoutOptions.maxWidth;
+		}
+
+		UINT32 contentWidth = style.margins.left + style.margins.right + style.contentOffset.left + style.contentOffset.right;
+		UINT32 contentHeight = style.margins.top + style.margins.bottom + style.contentOffset.top + style.contentOffset.bottom;
+
+		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(text, style.font, style.fontSize, wordWrapWidth, 0, style.wordWrap);
+
+		if(textData != nullptr)
+		{
+			contentWidth += textData->getWidth();
+			contentHeight += textData->getHeight();
+		}
+
+		return Int2(contentWidth, contentHeight);
+	}
+}

+ 7 - 8
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -17,6 +17,7 @@
 #include "BsGUIInputSelection.h"
 #include "BsGUIInputSelection.h"
 #include "BsDragAndDropManager.h"
 #include "BsDragAndDropManager.h"
 #include "BsGUIContextMenu.h"
 #include "BsGUIContextMenu.h"
+#include "BsGUIHelper.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
 
 
@@ -280,22 +281,20 @@ namespace BansheeEngine
 
 
 	UINT32 GUIInputBox::_getOptimalWidth() const
 	UINT32 GUIInputBox::_getOptimalWidth() const
 	{
 	{
+		UINT32 imageWidth = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getWidth();
-		}
+			imageWidth = mImageDesc.texture->getTexture()->getWidth();
 
 
-		return 0;
+		return std::max(imageWidth, (UINT32)GUIHelper::calcOptimalContentsSize(mText, *mStyle, _getLayoutOptions()).x);
 	}
 	}
 
 
 	UINT32 GUIInputBox::_getOptimalHeight() const
 	UINT32 GUIInputBox::_getOptimalHeight() const
 	{
 	{
+		UINT32 imageHeight = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getHeight();
-		}
+			imageHeight = mImageDesc.texture->getTexture()->getHeight();
 
 
-		return 0;
+		return std::max(imageHeight, (UINT32)GUIHelper::calcOptimalContentsSize(mText, *mStyle, _getLayoutOptions()).y);
 	}
 	}
 
 
 	CM::Int2 GUIInputBox::_getTextInputOffset() const
 	CM::Int2 GUIInputBox::_getTextInputOffset() const

+ 3 - 30
BansheeEngine/Source/BsGUILabel.cpp

@@ -4,6 +4,7 @@
 #include "BsGUISkin.h"
 #include "BsGUISkin.h"
 #include "BsGUIWidget.h"
 #include "BsGUIWidget.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
+#include "BsGUIHelper.h"
 #include "CmTextUtility.h"
 #include "CmTextUtility.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -60,40 +61,12 @@ namespace BansheeEngine
 
 
 	UINT32 GUILabel::_getOptimalWidth() const
 	UINT32 GUILabel::_getOptimalWidth() const
 	{
 	{
-		UINT32 wordWrapWidth = 0;
-
-		if(mDesc.wordWrap)
-		{
-			if(_getLayoutOptions().fixedWidth)
-				wordWrapWidth = _getLayoutOptions().width;
-			else
-				wordWrapWidth = _getLayoutOptions().maxWidth;
-		}
-
-		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(mDesc.text, mDesc.font, mDesc.fontSize, wordWrapWidth, 0, mDesc.wordWrap);
-		if(textData == nullptr)
-			return 0;
-
-		return textData->getWidth();
+		return GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).x;
 	}
 	}
 
 
 	UINT32 GUILabel::_getOptimalHeight() const
 	UINT32 GUILabel::_getOptimalHeight() const
 	{
 	{
-		UINT32 wordWrapWidth = 0;
-
-		if(mDesc.wordWrap)
-		{
-			if(_getLayoutOptions().fixedWidth)
-				wordWrapWidth = _getLayoutOptions().width;
-			else
-				wordWrapWidth = _getLayoutOptions().maxWidth;
-		}
-
-		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(mDesc.text, mDesc.font, mDesc.fontSize, wordWrapWidth, 0, mDesc.wordWrap);
-		if(textData == nullptr)
-			return 0;
-
-		return textData->getHeight();
+		return GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).y;
 	}
 	}
 
 
 	void GUILabel::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
 	void GUILabel::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 

+ 25 - 21
BansheeEngine/Source/BsGUIListBox.cpp

@@ -7,6 +7,7 @@
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIManager.h"
 #include "BsGUIManager.h"
+#include "BsGUIHelper.h"
 #include "CmTexture.h"
 #include "CmTexture.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -102,19 +103,7 @@ namespace BansheeEngine
 		mImageSprite->update(mImageDesc);
 		mImageSprite->update(mImageDesc);
 		mNumImageRenderElements = mImageSprite->getNumRenderElements();
 		mNumImageRenderElements = mImageSprite->getNumRenderElements();
 
 
-		TEXT_SPRITE_DESC textDesc;
-		textDesc.text = mElements[mSelectedIdx];
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
-
-		Rect textBounds = getContentBounds();
-
-		textDesc.width = textBounds.width;
-		textDesc.height = textBounds.height;
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
-
-		mTextSprite->update(textDesc);
+		mTextSprite->update(getTextDesc());
 
 
 		GUIElement::updateRenderElementsInternal();
 		GUIElement::updateRenderElementsInternal();
 	}
 	}
@@ -126,22 +115,20 @@ namespace BansheeEngine
 
 
 	UINT32 GUIListBox::_getOptimalWidth() const
 	UINT32 GUIListBox::_getOptimalWidth() const
 	{
 	{
+		UINT32 imageWidth = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getWidth();
-		}
+			imageWidth = mImageDesc.texture->getTexture()->getWidth();
 
 
-		return 0;
+		return std::max(imageWidth, (UINT32)GUIHelper::calcOptimalContentsSize(mElements[mSelectedIdx], *mStyle, _getLayoutOptions()).x);
 	}
 	}
 
 
 	UINT32 GUIListBox::_getOptimalHeight() const
 	UINT32 GUIListBox::_getOptimalHeight() const
 	{
 	{
+		UINT32 imageHeight = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getHeight();
-		}
+			imageHeight = mImageDesc.texture->getTexture()->getHeight();
 
 
-		return 0;
+		return std::max(imageHeight, (UINT32)GUIHelper::calcOptimalContentsSize(mElements[mSelectedIdx], *mStyle, _getLayoutOptions()).y);
 	}
 	}
 
 
 	UINT32 GUIListBox::_getRenderElementDepth(UINT32 renderElementIdx) const
 	UINT32 GUIListBox::_getRenderElementDepth(UINT32 renderElementIdx) const
@@ -216,4 +203,21 @@ namespace BansheeEngine
 
 
 		markContentAsDirty();
 		markContentAsDirty();
 	}
 	}
+
+	TEXT_SPRITE_DESC GUIListBox::getTextDesc() const
+	{
+		TEXT_SPRITE_DESC textDesc;
+		textDesc.text = mElements[mSelectedIdx];
+		textDesc.font = mStyle->font;
+		textDesc.fontSize = mStyle->fontSize;
+
+		Rect textBounds = getContentBounds();
+
+		textDesc.width = textBounds.width;
+		textDesc.height = textBounds.height;
+		textDesc.horzAlign = mStyle->textHorzAlign;
+		textDesc.vertAlign = mStyle->textVertAlign;
+
+		return textDesc;
+	}
 }
 }

+ 14 - 16
BansheeEngine/Source/BsGUIMenu.cpp

@@ -25,7 +25,17 @@ namespace BansheeEngine
 
 
 	const GUIMenuItem* GUIMenuItem::findChild(const CM::WString& name) const
 	const GUIMenuItem* GUIMenuItem::findChild(const CM::WString& name) const
 	{
 	{
-		auto iterFind = findChildInternal(name);
+		auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
+
+		if(iterFind != mChildren.end())
+			return *iterFind;
+
+		return nullptr;
+	}
+
+	GUIMenuItem* GUIMenuItem::findChild(const CM::WString& name)
+	{
+		auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
 
 
 		if(iterFind != mChildren.end())
 		if(iterFind != mChildren.end())
 			return *iterFind;
 			return *iterFind;
@@ -35,7 +45,7 @@ namespace BansheeEngine
 
 
 	void GUIMenuItem::removeChild(const CM::WString& name)
 	void GUIMenuItem::removeChild(const CM::WString& name)
 	{
 	{
-		auto iterFind = findChildInternal(name);
+		auto iterFind = std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
 
 
 		if(iterFind != mChildren.end())
 		if(iterFind != mChildren.end())
 		{
 		{
@@ -44,16 +54,6 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	CM::Vector<GUIMenuItem*>::type::const_iterator GUIMenuItem::findChildInternal(const CM::WString& name) const
-	{
-		return std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
-	}
-
-	CM::Vector<GUIMenuItem*>::type::iterator GUIMenuItem::findChildInternal(const CM::WString& name)
-	{
-		return std::find_if(begin(mChildren), end(mChildren), [&] (GUIMenuItem* x) { return x->getName() == name; });
-	}
-
 	GUIMenu::GUIMenu()
 	GUIMenu::GUIMenu()
 		:mRootElement(nullptr, L"", nullptr)
 		:mRootElement(nullptr, L"", nullptr)
 	{
 	{
@@ -83,8 +83,7 @@ namespace BansheeEngine
 		for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
 		for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
 		{
 		{
 			const WString& pathElem = *(pathElements.begin() + i);
 			const WString& pathElem = *(pathElements.begin() + i);
-			auto foundChild = curSubMenu->findChildInternal(pathElem);
-			GUIMenuItem* existingItem = *foundChild;
+			GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
 
 
 			if(existingItem == nullptr)
 			if(existingItem == nullptr)
 			{
 			{
@@ -125,8 +124,7 @@ namespace BansheeEngine
 		for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
 		for(UINT32 i = 0; i < (UINT32)pathElements.size(); i++)
 		{
 		{
 			const WString& pathElem = *(pathElements.begin() + i);
 			const WString& pathElem = *(pathElements.begin() + i);
-			auto foundChild = curSubMenu->findChildInternal(pathElem);
-			GUIMenuItem* existingItem = *foundChild;
+			const GUIMenuItem* existingItem = curSubMenu->findChild(pathElem);
 
 
 			if(existingItem == nullptr || existingItem->isSeparator())
 			if(existingItem == nullptr || existingItem->isSeparator())
 				return nullptr;
 				return nullptr;

+ 25 - 21
BansheeEngine/Source/BsGUIToggle.cpp

@@ -7,6 +7,7 @@
 #include "BsGUILayoutOptions.h"
 #include "BsGUILayoutOptions.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIMouseEvent.h"
 #include "BsGUIToggleGroup.h"
 #include "BsGUIToggleGroup.h"
+#include "BsGUIHelper.h"
 #include "CmTexture.h"
 #include "CmTexture.h"
 
 
 using namespace CamelotFramework;
 using namespace CamelotFramework;
@@ -246,19 +247,7 @@ namespace BansheeEngine
 		mImageSprite->update(mImageDesc);
 		mImageSprite->update(mImageDesc);
 		mNumImageRenderElements = mImageSprite->getNumRenderElements();
 		mNumImageRenderElements = mImageSprite->getNumRenderElements();
 
 
-		TEXT_SPRITE_DESC textDesc;
-		textDesc.text = mContent.getText();
-		textDesc.font = mStyle->font;
-		textDesc.fontSize = mStyle->fontSize;
-
-		Rect textBounds = getContentBounds();
-
-		textDesc.width = textBounds.width;
-		textDesc.height = textBounds.height;
-		textDesc.horzAlign = mStyle->textHorzAlign;
-		textDesc.vertAlign = mStyle->textVertAlign;
-
-		mTextSprite->update(textDesc);
+		mTextSprite->update(getTextDesc());
 
 
 		GUIElement::updateRenderElementsInternal();
 		GUIElement::updateRenderElementsInternal();
 	}
 	}
@@ -270,22 +259,20 @@ namespace BansheeEngine
 
 
 	UINT32 GUIToggle::_getOptimalWidth() const
 	UINT32 GUIToggle::_getOptimalWidth() const
 	{
 	{
+		UINT32 imageWidth = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getWidth();
-		}
+			imageWidth = mImageDesc.texture->getTexture()->getWidth();
 
 
-		return 0;
+		return std::max(imageWidth, (UINT32)GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).x);
 	}
 	}
 
 
 	UINT32 GUIToggle::_getOptimalHeight() const
 	UINT32 GUIToggle::_getOptimalHeight() const
 	{
 	{
+		UINT32 imageHeight = 0;
 		if(mImageDesc.texture != nullptr)
 		if(mImageDesc.texture != nullptr)
-		{
-			return mImageDesc.texture->getTexture()->getHeight();
-		}
+			imageHeight = mImageDesc.texture->getTexture()->getHeight();
 
 
-		return 0;
+		return std::max(imageHeight, (UINT32)GUIHelper::calcOptimalContentsSize(mContent, *mStyle, _getLayoutOptions()).y);
 	}
 	}
 
 
 	UINT32 GUIToggle::_getRenderElementDepth(UINT32 renderElementIdx) const
 	UINT32 GUIToggle::_getRenderElementDepth(UINT32 renderElementIdx) const
@@ -359,4 +346,21 @@ namespace BansheeEngine
 
 
 		return false;
 		return false;
 	}
 	}
+
+	TEXT_SPRITE_DESC GUIToggle::getTextDesc() const
+	{
+		TEXT_SPRITE_DESC textDesc;
+		textDesc.text = mContent.getText();
+		textDesc.font = mStyle->font;
+		textDesc.fontSize = mStyle->fontSize;
+
+		Rect textBounds = getContentBounds();
+
+		textDesc.width = textBounds.width;
+		textDesc.height = textBounds.height;
+		textDesc.horzAlign = mStyle->textHorzAlign;
+		textDesc.vertAlign = mStyle->textVertAlign;
+
+		return textDesc;
+	}
 }
 }

+ 3 - 1
CamelotClient/Source/BsGUIMenuBar.cpp

@@ -4,6 +4,7 @@
 #include "BsGUIButton.h"
 #include "BsGUIButton.h"
 #include "BsGUITexture.h"
 #include "BsGUITexture.h"
 #include "BsGUILayout.h"
 #include "BsGUILayout.h"
+#include "BsGUISpace.h"
 #include "BsGUIMenu.h"
 #include "BsGUIMenu.h"
 #include "BsGUIManager.h"
 #include "BsGUIManager.h"
 #include "BsEngineGUI.h"
 #include "BsEngineGUI.h"
@@ -24,6 +25,7 @@ namespace BansheeEditor
 
 
 		mLogoTexture = GUITexture::create(*parent, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBansheeLogo"));
 		mLogoTexture = GUITexture::create(*parent, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBansheeLogo"));
 		mMainArea->getLayout().addElement(mLogoTexture);
 		mMainArea->getLayout().addElement(mLogoTexture);
+		mMainArea->getLayout().addFlexibleSpace();
 	}
 	}
 
 
 	GUIMenuBar::~GUIMenuBar()
 	GUIMenuBar::~GUIMenuBar()
@@ -68,7 +70,7 @@ namespace BansheeEditor
 			newSubMenu.menu = cm_new<GUIMenu>();
 			newSubMenu.menu = cm_new<GUIMenu>();
 
 
 			GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
 			GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
-			mMainArea->getLayout().addElement(newButton);
+			mMainArea->getLayout().insertElement(mMainArea->getLayout().getNumChildren() - 1, newButton);
 
 
 			newSubMenu.button = newButton;
 			newSubMenu.button = newButton;
 
 

+ 6 - 1
CamelotClient/Source/BsMainEditorWindow.cpp

@@ -22,6 +22,11 @@ namespace BansheeEditor
 	{
 	{
 		updateAreas();
 		updateAreas();
 
 
+		mMenuBar->addMenuItem(L"File/New project", nullptr);
+		mMenuBar->addMenuItem(L"File/Open project", nullptr);
+		mMenuBar->addSeparator(L"File");
+		mMenuBar->addMenuItem(L"File/Exit", nullptr);
+
 		// DEBUG ONLY
 		// DEBUG ONLY
 
 
 		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
 		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
@@ -72,7 +77,7 @@ namespace BansheeEditor
 		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);
 		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);
 		UINT32 widgetHeight = (UINT32)std::max(0, (INT32)getHeight() - 2);
 		UINT32 widgetHeight = (UINT32)std::max(0, (INT32)getHeight() - 2);
 
 
-		UINT32 menuBarHeight = 20;
+		UINT32 menuBarHeight = 15;
 		mMenuBar->setArea(1, 1, widgetWidth, menuBarHeight);
 		mMenuBar->setArea(1, 1, widgetWidth, menuBarHeight);
 
 
 		UINT32 dockHeight = (UINT32)std::max(0, (INT32)widgetHeight - (INT32)menuBarHeight);
 		UINT32 dockHeight = (UINT32)std::max(0, (INT32)widgetHeight - (INT32)menuBarHeight);

+ 2 - 1
DropDown.txt

@@ -2,7 +2,8 @@ GUI ignores image in GUIContent for most elements.
 
 
 Doesn't belong here but as an additional reminder: Remove Component::initialize and instead make multi paramter addComponent
 Doesn't belong here but as an additional reminder: Remove Component::initialize and instead make multi paramter addComponent
 
 
-GUIContextMenu::getDropDownData needs to be implemented
+Add min/max/close buttons to GUIMenuBar
+Setup move areas in GUIMenuBar
 
 
 ListBox: Clicking on ListBox once the DropDownBox is open should close the drop down box (I assume it does, it just re-opens it immediately again?)
 ListBox: Clicking on ListBox once the DropDownBox is open should close the drop down box (I assume it does, it just re-opens it immediately again?)