Browse Source

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 years ago
parent
commit
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?)