فهرست منبع

Moved MenuBar to BansheeEditor
GUIMenuBar now properly removes root elements
Added MenuBar texture and style resources

Marko Pintera 12 سال پیش
والد
کامیت
7e7d516e1e

+ 0 - 2
BansheeEngine/BansheeEngine.vcxproj

@@ -250,7 +250,6 @@
     <ClInclude Include="Include\BsGUILayout.h" />
     <ClInclude Include="Include\BsGUILayoutY.h" />
     <ClInclude Include="Include\BsGUIMenu.h" />
-    <ClInclude Include="Include\BsGUIMenuBar.h" />
     <ClInclude Include="Include\BsGUIScrollBar.h" />
     <ClInclude Include="Include\BsGUIScrollBarHandle.h" />
     <ClInclude Include="Include\BsGUIScrollBarHorz.h" />
@@ -312,7 +311,6 @@
     <ClCompile Include="Source\BsGUILayoutY.cpp" />
     <ClCompile Include="Source\BsGUIManager.cpp" />
     <ClCompile Include="Source\BsGUIMaterialManager.cpp" />
-    <ClCompile Include="Source\BsGUIMenuBar.cpp" />
     <ClCompile Include="Source\BsGUIMouseEvent.cpp" />
     <ClCompile Include="Source\BsGUIScrollBar.cpp" />
     <ClCompile Include="Source\BsGUIScrollBarHandle.cpp" />

+ 0 - 6
BansheeEngine/BansheeEngine.vcxproj.filters

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

+ 10 - 0
BansheeEngine/Include/BsEngineGUI.h

@@ -33,6 +33,9 @@ namespace BansheeEngine
 		static const CM::String WindowMinButtonNormal;
 		static const CM::String WindowMinButtonHover;
 
+		static const CM::String WindowMaxButtonNormal;
+		static const CM::String WindowMaxButtonHover;
+
 		static const CM::String TabbedBarBtnNormal;
 		static const CM::String TabbedBarBtnActive;
 
@@ -86,5 +89,12 @@ namespace BansheeEngine
 
 		static const CM::String DropDownBoxBtnUpArrowTex;
 		static const CM::String DropDownBoxBtnDownArrowTex;
+
+		static const CM::String MenuBarBgTex;
+
+		static const CM::String MenuBarBtnNormalTex;
+		static const CM::String MenuBarBtnHoverTex;
+
+		static const CM::String MenuBarBansheeLogoTex;
 	};
 }

+ 0 - 1
BansheeEngine/Include/BsPrerequisites.h

@@ -61,7 +61,6 @@ namespace BansheeEngine
 	class GUIMenuItem;
 	class GUIContent;
 	class GUIContextMenu;
-	class GUIMenuBar;
 
 	// 2D
 	class TextSprite;

+ 74 - 4
BansheeEngine/Source/BsEngineGUI.cpp

@@ -33,8 +33,11 @@ namespace BansheeEngine
 	const String EngineGUI::WindowCloseButtonNormal = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowCloseBtnNormal.psd";
 	const String EngineGUI::WindowCloseButtonHover = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowCloseBtnHover.psd";
 
-	const String EngineGUI::WindowMinButtonNormal = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMinBtnNormal.psd";
-	const String EngineGUI::WindowMinButtonHover = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMinBtnHover.psd";
+	const String EngineGUI::WindowMinButtonNormal = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMaxBtnNormal.psd";
+	const String EngineGUI::WindowMinButtonHover = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMaxBtnHover.psd";
+
+	const String EngineGUI::WindowMaxButtonNormal = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMinBtnNormal.psd";
+	const String EngineGUI::WindowMaxButtonHover = "..\\..\\..\\..\\Data\\Editor\\Skin\\WindowMinBtnHover.psd";
 
 	const String EngineGUI::TabbedBarBtnNormal = "..\\..\\..\\..\\Data\\Editor\\Skin\\TabbedButtonNormal.psd";
 	const String EngineGUI::TabbedBarBtnActive = "..\\..\\..\\..\\Data\\Editor\\Skin\\TabbedButtonActive.psd";
@@ -87,6 +90,13 @@ namespace BansheeEngine
 
 	const String EngineGUI::ScrollBarBgTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\ScrollBarBg.psd";
 
+	const String EngineGUI::MenuBarBgTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\MenuBarBg.psd";
+
+	const String EngineGUI::MenuBarBtnNormalTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\MenuBarButtonNormal.psd";
+	const String EngineGUI::MenuBarBtnHoverTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\MenuBarButtonHover.psd";
+
+	const String EngineGUI::MenuBarBansheeLogoTex = "..\\..\\..\\..\\Data\\Editor\\Skin\\MenuBarBansheeLogo.psd";
+
 	EngineGUI::EngineGUI()
 	{
 		// TODO - Normally I want to load this from some file
@@ -225,6 +235,21 @@ namespace BansheeEngine
 
 		mSkin.setStyle("WinMinimizeBtn", winMinButtonStyle);
 
+		// Window maximize button
+		HTexture winMaxBtnNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowMaxButtonNormal));
+		HTexture winMaxBtnHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowMaxButtonHover));
+
+		GUIElementStyle winMaxButtonStyle;
+		winMaxButtonStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(winMaxBtnNormal));
+		winMaxButtonStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(winMaxBtnHover));
+		winMaxButtonStyle.active.texture = winMaxButtonStyle.hover.texture;
+		winMaxButtonStyle.fixedHeight = true;
+		winMaxButtonStyle.fixedWidth = true;
+		winMaxButtonStyle.height = 8;
+		winMaxButtonStyle.width = 8;
+
+		mSkin.setStyle("WinMaximizeBtn", winMaxButtonStyle);
+
 		// Window close button
 		HTexture winCloseBtnNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowCloseButtonNormal));
 		HTexture winCloseBtnHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + WindowCloseButtonHover));
@@ -583,8 +608,6 @@ namespace BansheeEngine
 
 		GUIElementStyle dropDownSeparatorStyle;
 		dropDownSeparatorStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(dropDownSeparatorTex));
-		dropDownSeparatorStyle.hover.texture = dropDownSeparatorStyle.normal.texture;
-		dropDownSeparatorStyle.active.texture = dropDownSeparatorStyle.hover.texture;
 		dropDownSeparatorStyle.fixedHeight = true;
 		dropDownSeparatorStyle.fixedWidth = false;
 		dropDownSeparatorStyle.height = 3;
@@ -597,5 +620,52 @@ namespace BansheeEngine
 		mSkin.setStyle("ListBoxSeparator", dropDownSeparatorStyle);
 		mSkin.setStyle("MenuBarSeparator", dropDownSeparatorStyle);
 		mSkin.setStyle("ContextMenuSeparator", dropDownSeparatorStyle);
+
+		/************************************************************************/
+		/* 								MENU BAR	                     		*/
+		/************************************************************************/
+
+		// MenuBar background
+		HTexture menuBarBgTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + MenuBarBgTex));
+
+		GUIElementStyle menuBarBgStyle;
+		menuBarBgStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBgTex));
+		menuBarBgStyle.fixedHeight = false;
+		menuBarBgStyle.fixedWidth = false;
+		menuBarBgStyle.height = 4;
+		menuBarBgStyle.width = 4;
+
+		mSkin.setStyle("MenuBarBg", menuBarBgStyle);
+
+		// MenuBar Banshee logo
+		HTexture menuBarBansheeLogoTex = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + MenuBarBansheeLogoTex));
+
+		GUIElementStyle menuBarBansheeLogoStyle;
+		menuBarBansheeLogoStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBansheeLogoTex));
+		menuBarBansheeLogoStyle.fixedHeight = true;
+		menuBarBansheeLogoStyle.fixedWidth = true;
+		menuBarBansheeLogoStyle.height = 7;
+		menuBarBansheeLogoStyle.width = 51;
+
+		mSkin.setStyle("MenuBarBansheeLogo", menuBarBansheeLogoStyle);
+
+		// MenuBar button
+		HTexture menuBarBtnNormal = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + MenuBarBtnNormalTex));
+		HTexture menuBarBtnHover = static_resource_cast<Texture>(Importer::instance().import(FileSystem::getCurrentPath() + "\\" + MenuBarBtnHoverTex));
+
+		GUIElementStyle menuBarBtnStyle;
+		menuBarBtnStyle.normal.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnNormal));
+		menuBarBtnStyle.hover.texture = cm_shared_ptr<SpriteTexture, PoolAlloc>(std::cref(menuBarBtnHover));
+		menuBarBtnStyle.active.texture = menuBarBtnStyle.hover.texture;
+		menuBarBtnStyle.fixedHeight = false;
+		menuBarBtnStyle.fixedWidth = false;
+		menuBarBtnStyle.height = 4;
+		menuBarBtnStyle.width = 4;
+		menuBarBtnStyle.font = font;
+		menuBarBtnStyle.fontSize = DefaultFontSize;
+		menuBarBtnStyle.textHorzAlign = THA_Left;
+		menuBarBtnStyle.textVertAlign = TVA_Top;
+
+		mSkin.setStyle("MenuBarBtn", menuBarBtnStyle);
 	}
 }

+ 2 - 0
CamelotClient/CamelotClient.vcxproj

@@ -262,6 +262,7 @@
     <ClInclude Include="Include\BsEditorWindow.h" />
     <ClInclude Include="Include\BsEditorWindowBase.h" />
     <ClInclude Include="Include\BsEditorWindowManager.h" />
+    <ClInclude Include="Include\BsGUIMenuBar.h" />
     <ClInclude Include="Include\BsGUITabbedTitleBar.h" />
     <ClInclude Include="Include\BsGUITabButton.h" />
     <ClInclude Include="Include\BsGUIWindowFrame.h" />
@@ -283,6 +284,7 @@
     <ClCompile Include="Source\BsEditorWindow.cpp" />
     <ClCompile Include="Source\BsEditorWindowBase.cpp" />
     <ClCompile Include="Source\BsEditorWindowManager.cpp" />
+    <ClCompile Include="Source\BsGUIMenuBar.cpp" />
     <ClCompile Include="Source\BsGUITabbedTitleBar.cpp" />
     <ClCompile Include="Source\BsGUITabButton.cpp" />
     <ClCompile Include="Source\BsGUIWindowFrame.cpp" />

+ 6 - 0
CamelotClient/CamelotClient.vcxproj.filters

@@ -81,6 +81,9 @@
     <ClInclude Include="Include\BsGUIWindowFrame.h">
       <Filter>Header Files\Editor</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIMenuBar.h">
+      <Filter>Header Files\Editor</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">
@@ -137,5 +140,8 @@
     <ClCompile Include="Source\BsGUIWindowFrame.cpp">
       <Filter>Source Files\Editor</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIMenuBar.cpp">
+      <Filter>Source Files\Editor</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 0
CamelotClient/Include/BsEditorPrerequisites.h

@@ -17,6 +17,7 @@ namespace BansheeEditor
 	class DockManager;
 	class MainEditorWindow;
 	class WindowFrameWidget;
+	class GUIMenuBar;
 
 	enum class DragAndDropType
 	{

+ 48 - 0
CamelotClient/Include/BsGUIMenuBar.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include "BsEditorPrerequisites.h"
+
+namespace BansheeEditor
+{
+	class GUIMenuBar
+	{
+		struct GUIMenuBarData
+		{
+			CM::WString name;
+			BS::GUIMenu* menu;
+			BS::GUIButton* button;
+		};
+
+	public:
+		GUIMenuBar(BS::GUIWidget* parent);
+		virtual ~GUIMenuBar();
+
+		void setArea(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height);
+
+		const BS::GUIMenuItem* addMenuItem(const CM::WString& path, std::function<void()> callback);
+		const BS::GUIMenuItem* addSeparator(const CM::WString& path);
+		const BS::GUIMenuItem* getMenuItem(const CM::WString& path) const;
+		void removeMenuItem(const CM::WString& path);
+	private:
+		BS::GUIWidget* mParentWidget;
+		BS::GUIArea* mMainArea;
+		BS::GUIArea* mBackgroundArea;
+		BS::GUITexture* mBgTexture;
+		BS::GUITexture* mLogoTexture;
+
+		CM::Vector<GUIMenuBarData>::type mChildMenus;
+
+		const GUIMenuBarData* getSubMenu(const CM::WString& name) const;
+
+		/**
+		 * @brief	Attempts to remove the first element from the specified path. First element
+		 * 			returned in specified in "pathRoot", and original "path" parameter is modified so
+		 * 			it no longer includes the first element.
+		 *
+		 * @return	False if first element doesn't exist, true otherwise.
+		 */
+		bool stripPath(CM::WString& path, CM::WString& pathRoot) const;
+
+		void openSubMenu(const CM::WString& name);
+	};
+}

+ 3 - 1
CamelotClient/Include/BsMainEditorWindow.h

@@ -12,9 +12,11 @@ namespace BansheeEditor
 		~MainEditorWindow();
 
 	protected:
-		BS::GUIMenuBar* mMenuBar;
+		GUIMenuBar* mMenuBar;
 		DockManager* mDockManager;
 
 		virtual void movedOrResized();
+
+		void updateAreas();
 	};
 }

+ 205 - 0
CamelotClient/Source/BsGUIMenuBar.cpp

@@ -0,0 +1,205 @@
+#include "BsGUIMenuBar.h"
+#include "BsGUIArea.h"
+#include "BsGUIElement.h"
+#include "BsGUIButton.h"
+#include "BsGUITexture.h"
+#include "BsGUILayout.h"
+#include "BsGUIMenu.h"
+#include "BsGUIManager.h"
+#include "BsEngineGUI.h"
+
+using namespace CamelotFramework;
+using namespace BansheeEngine;
+
+namespace BansheeEditor
+{
+	GUIMenuBar::GUIMenuBar(BS::GUIWidget* parent)
+		:mParentWidget(parent), mMainArea(nullptr), mBackgroundArea(nullptr), mBgTexture(nullptr), mLogoTexture(nullptr)
+	{
+		mBackgroundArea = GUIArea::create(*parent, 0, 0, 1, 13, 9900);
+		mMainArea = GUIArea::create(*parent, 0, 0, 1, 13, 9899);
+
+		mBgTexture = GUITexture::create(*parent, GUILayoutOptions::expandableXY(), GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBg"));
+		mBackgroundArea->getLayout().addElement(mBgTexture);
+
+		mLogoTexture = GUITexture::create(*parent, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("MenuBarBansheeLogo"));
+		mMainArea->getLayout().addElement(mLogoTexture);
+	}
+
+	GUIMenuBar::~GUIMenuBar()
+	{
+		for(auto& menu : mChildMenus)
+		{
+			cm_delete<PoolAlloc>(menu.menu);
+			GUIElement::destroy(menu.button);
+		}
+
+		GUIElement::destroy(mBgTexture);
+		GUIElement::destroy(mLogoTexture);
+
+		GUIArea::destroy(mMainArea);
+		GUIArea::destroy(mBackgroundArea);
+	}
+
+	void GUIMenuBar::setArea(CM::INT32 x, CM::INT32 y, CM::UINT32 width, CM::UINT32 height)
+	{
+		mMainArea->setPosition(x, y);
+		mBackgroundArea->setPosition(x, y);
+
+		mMainArea->setSize(width, height);
+		mBackgroundArea->setSize(width, height);
+	}
+
+	const GUIMenuItem* GUIMenuBar::addMenuItem(const CM::WString& path, std::function<void()> callback)
+	{
+		WString strippedPath = path;
+		WString rootName;
+
+		if(!stripPath(strippedPath, rootName))
+			return nullptr;
+
+		const GUIMenuBarData* subMenu = getSubMenu(rootName);
+		if(subMenu == nullptr)
+		{
+			mChildMenus.push_back(GUIMenuBarData());
+
+			GUIMenuBarData& newSubMenu = mChildMenus.back();
+			newSubMenu.name = rootName;
+			newSubMenu.menu = cm_new<GUIMenu>();
+
+			GUIButton* newButton = GUIButton::create(*mParentWidget, rootName, EngineGUI::instance().getSkin().getStyle("MenuBarBtn"));
+			mMainArea->getLayout().addElement(newButton);
+
+			newSubMenu.button = newButton;
+
+			subMenu = &newSubMenu;
+		}
+
+		return subMenu->menu->addMenuItem(strippedPath, callback);
+	}
+
+	const GUIMenuItem* GUIMenuBar::addSeparator(const CM::WString& path)
+	{
+		WString strippedPath = path;
+		WString rootName;
+
+		if(!stripPath(strippedPath, rootName))
+			return nullptr;
+
+		const GUIMenuBarData* subMenu = getSubMenu(rootName);
+		if(subMenu == nullptr)
+		{
+			mChildMenus.push_back(GUIMenuBarData());
+
+			GUIMenuBarData& newSubMenu = mChildMenus.back();
+			newSubMenu.name = rootName;
+			newSubMenu.menu = cm_new<GUIMenu>();
+
+			GUIButton* newButton = GUIButton::create(*mParentWidget, rootName);
+			newButton->onClick.connect(boost::bind(&GUIMenuBar::openSubMenu, this, rootName));
+			mMainArea->getLayout().addElement(newButton);
+
+			newSubMenu.button = newButton;
+
+			subMenu = &newSubMenu;
+		}
+
+		return subMenu->menu->addSeparator(strippedPath);
+	}
+
+	const GUIMenuItem* GUIMenuBar::getMenuItem(const CM::WString& path) const
+	{
+		WString strippedPath = path;
+		WString rootName;
+
+		if(!stripPath(strippedPath, rootName))
+			return nullptr;
+
+		const GUIMenuBarData* subMenu = getSubMenu(rootName);
+		if(subMenu == nullptr)
+			return nullptr;
+
+		return subMenu->menu->getMenuItem(strippedPath);
+	}
+
+	void GUIMenuBar::removeMenuItem(const CM::WString& path)
+	{
+		WString strippedPath = path;
+		WString rootName;
+
+		if(!stripPath(strippedPath, rootName))
+			return;
+
+		if(strippedPath == L"")
+		{
+			UINT32 curIdx = 0;
+			GUIMenuBarData* subMenuToRemove = nullptr;
+			for(auto& subMenuData : mChildMenus)
+			{
+				if(subMenuData.name == rootName)
+				{
+					subMenuToRemove = &subMenuData;
+					break;
+				}
+
+				curIdx++;
+			}
+
+			if(subMenuToRemove == nullptr)
+				return;
+
+			mMainArea->getLayout().removeElement(subMenuToRemove->button);
+			GUIElement::destroy(subMenuToRemove->button);
+			cm_delete<PoolAlloc>(subMenuToRemove->menu);
+
+			mChildMenus.erase(mChildMenus.begin() + curIdx);
+
+			return;
+		}
+
+		const GUIMenuBarData* subMenu = getSubMenu(rootName);
+		if(subMenu == nullptr)
+			return;
+
+		const GUIMenuItem* item = subMenu->menu->getMenuItem(strippedPath);
+		if(item == nullptr)
+			return;
+
+		subMenu->menu->removeMenuItem(item);
+	}
+
+	const GUIMenuBar::GUIMenuBarData* GUIMenuBar::getSubMenu(const CM::WString& name) const
+	{
+		for(auto& subMenu : mChildMenus)
+		{
+			if(subMenu.name == name)
+				return &subMenu;
+		}
+
+		return nullptr;
+	}
+
+	bool GUIMenuBar::stripPath(CM::WString& path, CM::WString& pathRoot) const
+	{
+		Vector<WString>::type pathElements = StringUtil::split(path, L"/");
+		if(pathElements.size() == 0)
+			return false;
+
+		pathRoot = pathElements[0];
+		path.erase(0, pathRoot.size());
+
+		if(path.size() > 0)
+			path.erase(0, 1); // Forward slash
+
+		return true;
+	}
+
+	void GUIMenuBar::openSubMenu(const CM::WString& name)
+	{
+		const GUIMenuBarData* subMenu = getSubMenu(name);
+		if(subMenu == nullptr)
+			return;
+
+		GUIManager::instance().openMenuBarMenu(subMenu->button, subMenu->menu);
+	}
+}

+ 11 - 9
CamelotClient/Source/BsMainEditorWindow.cpp

@@ -20,14 +20,7 @@ namespace BansheeEditor
 	MainEditorWindow::MainEditorWindow(CM::RenderWindowPtr renderWindow)
 		:EditorWindowBase(renderWindow), mDockManager(cm_new<DockManager>(mGUI.get())), mMenuBar(cm_new<GUIMenuBar>(mGUI.get()))
 	{
-		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);
-		UINT32 widgetHeight = (UINT32)std::max(0, (INT32)getHeight() - 2);
-
-		UINT32 menuBarHeight = 20;
-		mMenuBar->setArea(1, 1, widgetWidth, menuBarHeight);
-
-		UINT32 dockHeight = (UINT32)std::max(0, (INT32)widgetHeight - (INT32)menuBarHeight);
-		mDockManager->setArea(1, menuBarHeight + 1, widgetWidth, dockHeight);
+		updateAreas();
 
 		// DEBUG ONLY
 
@@ -71,9 +64,18 @@ namespace BansheeEditor
 	{
 		EditorWindowBase::movedOrResized();
 
+		updateAreas();
+	}
+
+	void MainEditorWindow::updateAreas()
+	{
 		UINT32 widgetWidth = (UINT32)std::max(0, (INT32)getWidth() - 2);
 		UINT32 widgetHeight = (UINT32)std::max(0, (INT32)getHeight() - 2);
 
-		mDockManager->setArea(1, 1, widgetWidth, widgetHeight);
+		UINT32 menuBarHeight = 20;
+		mMenuBar->setArea(1, 1, widgetWidth, menuBarHeight);
+
+		UINT32 dockHeight = (UINT32)std::max(0, (INT32)widgetHeight - (INT32)menuBarHeight);
+		mDockManager->setArea(1, menuBarHeight + 1, widgetWidth, dockHeight);
 	}
 }