瀏覽代碼

Even more layout changes

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

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -189,6 +189,7 @@
     <ClCompile Include="Source\BsGUIElement.cpp" />
     <ClCompile Include="Source\BsGUILabel.cpp" />
     <ClCompile Include="Source\BsGUILayout.cpp" />
+    <ClCompile Include="Source\BsGUILayoutY.cpp" />
     <ClCompile Include="Source\BsGUIManager.cpp" />
     <ClCompile Include="Source\BsGUIMaterialManager.cpp" />
     <ClCompile Include="Source\BsGUISkin.cpp" />
@@ -208,6 +209,7 @@
     <ClCompile Include="Source\BsD3D9BuiltinMaterialFactory.cpp" />
     <ClCompile Include="Source\BsGLBuiltinMaterialFactory.cpp" />
     <ClCompile Include="Source\BsUpdateCallback.cpp" />
+    <ClCompile Include="Source\BsGUILayoutX.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -218,5 +218,11 @@
     <ClCompile Include="Source\BsGUILayout.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsGUILayoutX.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGUILayoutY.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 7 - 5
BansheeEngine/Include/BsGUIArea.h

@@ -17,24 +17,26 @@ namespace BansheeEngine
 		static GUIArea* create(GUIWidget& widget, UINT32 x, UINT32 y, UINT32 width = 0, UINT32 height = 0, UINT32 depth = 0);
 		static void destroy(GUIArea* area);
 
-		/**
-		 * @brief	Never call this manually. It's used by internal GUI systems.
-		 */
-		static void destroyInternal(GUIArea* area);
-
 		GUILayout& getLayout() const { return *mLayout; }
 
 		UINT32 getDepth() const { return mDepth; }
 		void setDepth(UINT32 depth) { mDepth = depth; }
 
 	private:
+		friend class GUIWidget;
+
 		GUIWidget& mWidget;
 		UINT32 mX, mY, mWidth, mHeight;
 		UINT32 mDepth;
+		bool resizeWidthWithWindow, resizeHeightWithWindow;
 
 		GUILayout* mLayout;
 
 		GUIArea(GUIWidget& widget, UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth);
 		~GUIArea();
+
+		void notifyWindowResized(UINT32 newWidth, UINT32 newHeight);
+
+		static void destroyInternal(GUIArea* area);
 	};
 }

+ 1 - 1
BansheeEngine/Include/BsGUIElement.h

@@ -9,7 +9,7 @@ namespace BansheeEngine
 	class BS_EXPORT GUIElement
 	{
 	public:
-		GUIElement(GUIWidget& parent);
+		GUIElement(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions);
 
 		/**
 		 * @brief	Returns the number of separate render elements in the GUI element.

+ 8 - 9
BansheeEngine/Include/BsGUILabel.h

@@ -11,13 +11,13 @@ namespace BansheeEngine
 	public:
 		static const CM::String& getGUITypeName();
 
-		static GUILabel* create(GUIWidget& parent, const CM::String& text, const GUI_LAYOUT_OPTIONS* layoutOptions = nullptr);
+		static GUILabel* create(GUIWidget& parent, const CM::String& text, bool wordWrap = false);
+		static GUILabel* create(GUIWidget& parent, const CM::String& text, const GUI_LAYOUT_OPTIONS& layoutOptions, bool wordWrap = false);
+
 		static GUILabel* create(GUIWidget& parent, const CM::String& text, TextHorzAlign horzAlign, 
-			TextVertAlign vertAlign = TVA_Top, const GUI_LAYOUT_OPTIONS* layoutOptions = nullptr);
-		static GUILabel* create(GUIWidget& parent, const CM::String& text, UINT32 fixedWidth, UINT32 fixedHeight = 0, 
-			bool wordWrap = false, const GUI_LAYOUT_OPTIONS* layoutOptions = nullptr);
-		static GUILabel* create(GUIWidget& parent, const CM::String& text, UINT32 fixedWidth, UINT32 fixedHeight, bool wordWrap, TextHorzAlign horzAlign, 
-			TextVertAlign vertAlign = TVA_Top, const GUI_LAYOUT_OPTIONS* layoutOptions = nullptr);
+			TextVertAlign vertAlign = TVA_Top, bool wordWrap = false);
+		static GUILabel* create(GUIWidget& parent, const CM::String& text, const GUI_LAYOUT_OPTIONS& layoutOptions,
+			TextHorzAlign horzAlign, TextVertAlign vertAlign = TVA_Top, bool wordWrap = false);
 
 		void setText(const CM::String& text);
 
@@ -49,13 +49,12 @@ namespace BansheeEngine
 	private:
 		TextSprite* mTextSprite;
 		CM::String mText;
-		UINT32 mFixedWidth, mFixedHeight;
 		bool mWordWrap;
 		TextHorzAlign mHorzAlign;
 		TextVertAlign mVertAlign;
 		TEXT_SPRITE_DESC mDesc;
 		
-		GUILabel(GUIWidget& parent, const CM::String& text, UINT32 fixedWidth, UINT32 fixedHeight, 
-			bool wordWrap, TextHorzAlign horzAlign, TextVertAlign vertAlign, const GUI_LAYOUT_OPTIONS* layoutOptions);
+		GUILabel(GUIWidget& parent, const CM::String& text, bool wordWrap, TextHorzAlign horzAlign, TextVertAlign vertAlign, 
+			const GUI_LAYOUT_OPTIONS& layoutOptions);
 	};
 }

+ 5 - 0
BansheeEngine/Include/BsGUILayout.h

@@ -36,7 +36,12 @@ namespace BansheeEngine
 		 */
 		UINT32 getNumChildren() const;
 
+	protected:
+		virtual void update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth) = 0;
+
 	private:
+		friend class GUIArea;
+
 		std::vector<GUILayoutEntry> mChildren;
 	};
 }

+ 3 - 0
BansheeEngine/Include/BsGUILayoutX.h

@@ -10,5 +10,8 @@ namespace BansheeEngine
 	public:
 		GUILayoutX() {};
 		~GUILayoutX() {};
+
+	protected:
+		void update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth);
 	};
 }

+ 3 - 0
BansheeEngine/Include/BsGUILayoutY.h

@@ -10,5 +10,8 @@ namespace BansheeEngine
 	public:
 		GUILayoutY() {};
 		~GUILayoutY() {};
+
+	protected:
+		virtual void update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth);
 	};
 }

+ 2 - 0
BansheeEngine/Include/BsGUIWidget.h

@@ -47,6 +47,8 @@ namespace BansheeEngine
 		void updateMeshes() const;
 		void updateBounds() const;
 
+		void ownerWindowResized(CM::RenderWindow* window);
+
 		const CM::RenderWindow* mOwnerWindow;
 		std::vector<GUIElement*> mElements;
 		std::vector<GUIArea*> mAreas;

+ 3 - 2
BansheeEngine/Include/BsGUIWindowFrame.h

@@ -11,7 +11,8 @@ namespace BansheeEngine
 	public:
 		static const CM::String& getGUITypeName();
 
-		static GUIWindowFrame* create(GUIWidget& parent, const GUI_LAYOUT_OPTIONS* layoutOptions = nullptr);
+		static GUIWindowFrame* create(GUIWidget& parent);
+		static GUIWindowFrame* create(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions);
 	protected:
 		~GUIWindowFrame();
 
@@ -40,6 +41,6 @@ namespace BansheeEngine
 	private:
 		ImageSprite* mImageSprite;
 
-		GUIWindowFrame(GUIWidget& parent, const GUI_LAYOUT_OPTIONS* layoutOptions);
+		GUIWindowFrame(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions);
 	};
 }

+ 15 - 0
BansheeEngine/Source/BsGUIArea.cpp

@@ -11,6 +11,9 @@ namespace BansheeEngine
 	{
 		mLayout = CM_NEW(GUILayoutX, PoolAlloc) GUILayoutX();
 
+		resizeWidthWithWindow = width == 0;
+		resizeHeightWithWindow = height == 0;
+
 		mWidget.registerArea(this);
 	}
 
@@ -35,4 +38,16 @@ namespace BansheeEngine
 	{
 		CM_DELETE(area, GUIArea, PoolAlloc);
 	}
+
+	void GUIArea::notifyWindowResized(UINT32 newWidth, UINT32 newHeight)
+	{
+		if(resizeWidthWithWindow)
+			mWidth = newWidth;
+
+		if(resizeHeightWithWindow)
+			mHeight = newHeight;
+
+		if(resizeWidthWithWindow || resizeHeightWithWindow)
+			mLayout->update(mX, mY, mWidth, mHeight, mDepth);
+	}
 }

+ 2 - 2
BansheeEngine/Source/BsGUIElement.cpp

@@ -8,8 +8,8 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	GUIElement::GUIElement(GUIWidget& parent)
-		:mParent(parent), mIsDirty(true), mParentLayout(nullptr)
+	GUIElement::GUIElement(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions)
+		:mParent(parent), mIsDirty(true), mParentLayout(nullptr), mLayoutOptions(layoutOptions)
 	{
 		mParent.registerElement(this);
 	}

+ 12 - 23
BansheeEngine/Source/BsGUILabel.cpp

@@ -9,9 +9,9 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	GUILabel::GUILabel(GUIWidget& parent, const String& text, UINT32 fixedWidth, UINT32 fixedHeight, 
-		bool wordWrap, TextHorzAlign horzAlign, TextVertAlign vertAlign, const GUI_LAYOUT_OPTIONS* layoutOptions)
-		:GUIElement(parent), mText(text), mFixedWidth(fixedWidth), mFixedHeight(fixedHeight), mWordWrap(wordWrap),
+	GUILabel::GUILabel(GUIWidget& parent, const String& text, bool wordWrap, TextHorzAlign horzAlign, 
+		TextVertAlign vertAlign, const GUI_LAYOUT_OPTIONS& layoutOptions)
+		:GUIElement(parent, layoutOptions), mText(text), mWordWrap(wordWrap),
 		mHorzAlign(horzAlign), mVertAlign(vertAlign)
 	{
 		const GUISkin* skin = parent.getGUISkin();
@@ -22,20 +22,12 @@ namespace BansheeEngine
 		mDesc.text = text;
 		mDesc.font = mStyle->font;
 		mDesc.fontSize = mStyle->fontSize;
-		mDesc.width = fixedWidth;
-		mDesc.height = fixedHeight;
 		mDesc.wordWrap = wordWrap;
-		mDesc.clipRect = Rect(0, 0, fixedWidth, fixedHeight);
 		mDesc.horzAlign = horzAlign;
 		mDesc.vertAlign = vertAlign;
-		mTextSprite->update(mDesc);
+		mTextSprite->update(mDesc); // TODO - I probably don't need to call this until I have GUILayout set up
 
 		mBounds = mTextSprite->getBounds();
-
-		if(layoutOptions != nullptr)
-			mLayoutOptions = *layoutOptions;
-		else
-			mLayoutOptions = getDefaultLayoutOptions();
 	}
 
 	GUILabel::~GUILabel()
@@ -92,27 +84,24 @@ namespace BansheeEngine
 		markAsDirty();
 	}
 
-	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, const GUI_LAYOUT_OPTIONS* layoutOptions)
+	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, bool wordWrap)
 	{
-		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, 0, 0, false, THA_Left, TVA_Top, layoutOptions);
+		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, wordWrap, THA_Left, TVA_Top, getDefaultLayoutOptions());
 	}
 
-	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, TextHorzAlign horzAlign, TextVertAlign vertAlign, 
-		const GUI_LAYOUT_OPTIONS* layoutOptions)
+	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, const GUI_LAYOUT_OPTIONS& layoutOptions, bool wordWrap)
 	{
-		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, 0, 0, false, horzAlign, vertAlign, layoutOptions);
+		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, wordWrap, THA_Left, TVA_Top, layoutOptions);
 	}
 
-	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, UINT32 fixedWidth, UINT32 fixedHeight, bool wordWrap, 
-		const GUI_LAYOUT_OPTIONS* layoutOptions)
+	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, TextHorzAlign horzAlign, TextVertAlign vertAlign, bool wordWrap)
 	{
-		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, fixedWidth, fixedHeight, wordWrap, THA_Left, TVA_Top, layoutOptions);
+		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, wordWrap, horzAlign, vertAlign, getDefaultLayoutOptions());
 	}
 
-	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, UINT32 fixedWidth, UINT32 fixedHeight, bool wordWrap, 
-		TextHorzAlign horzAlign, TextVertAlign vertAlign, const GUI_LAYOUT_OPTIONS* layoutOptions)
+	GUILabel* GUILabel::create(GUIWidget& parent, const String& text, const GUI_LAYOUT_OPTIONS& layoutOptions, TextHorzAlign horzAlign, TextVertAlign vertAlign, bool wordWrap)
 	{
-		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, fixedWidth, fixedHeight, wordWrap, horzAlign, vertAlign, layoutOptions);
+		return CM_NEW(GUILabel, PoolAlloc) GUILabel(parent, text, wordWrap, horzAlign, vertAlign, layoutOptions);
 	}
 
 	const String& GUILabel::getGUITypeName()

+ 9 - 0
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -0,0 +1,9 @@
+#include "BsGUILayoutX.h"
+
+namespace BansheeEngine
+{
+	void GUILayoutX::update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth)
+	{
+
+	}
+}

+ 9 - 0
BansheeEngine/Source/BsGUILayoutY.cpp

@@ -0,0 +1,9 @@
+#include "BsGUILayoutY.h"
+
+namespace BansheeEngine
+{
+	void GUILayoutY::update(UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 depth)
+	{
+
+	}
+}

+ 24 - 0
BansheeEngine/Source/BsGUIWidget.cpp

@@ -14,6 +14,7 @@
 #include "BsCamera.h"
 #include "CmViewport.h"
 #include "CmSceneObject.h"
+#include "CmRenderWindow.h"
 
 using namespace CamelotFramework;
 
@@ -46,13 +47,22 @@ namespace BansheeEngine
 
 	void GUIWidget::initialize(Viewport* target, const RenderWindow* ownerWindow)
 	{
+		assert(target != nullptr);
+		assert(ownerWindow != nullptr);
+
+		if(mOwnerWindow != nullptr)
+			CM_EXCEPT(InvalidStateException, "Widget has already been initialized.");
+
 		Overlay::initialize(target);
 
 		mOwnerWindow = ownerWindow;
+		mOwnerWindow->onWindowMovedOrResized.connect(boost::bind(&GUIWidget::ownerWindowResized, this, _1));
 	}
 
 	void GUIWidget::registerElement(GUIElement* elem)
 	{
+		assert(elem != nullptr);
+
 		mElements.push_back(elem);
 
 		mWidgetIsDirty = true;
@@ -60,6 +70,8 @@ namespace BansheeEngine
 
 	void GUIWidget::unregisterElement(GUIElement* elem)
 	{
+		assert(elem != nullptr);
+
 		auto iterFind = std::find(begin(mElements), end(mElements), elem);
 
 		if(iterFind == mElements.end())
@@ -71,6 +83,8 @@ namespace BansheeEngine
 
 	void GUIWidget::registerArea(GUIArea* area)
 	{
+		assert(area != nullptr);
+
 		mAreas.push_back(area);
 
 		mWidgetIsDirty = true;
@@ -78,6 +92,8 @@ namespace BansheeEngine
 
 	void GUIWidget::unregisterArea(GUIArea* area)
 	{
+		assert(area != nullptr);
+
 		auto iterFind = std::find(begin(mAreas), end(mAreas), area);
 
 		if(iterFind == mAreas.end())
@@ -265,6 +281,14 @@ namespace BansheeEngine
 		}
 	}
 
+	void GUIWidget::ownerWindowResized(RenderWindow* window)
+	{
+		for(auto& area : mAreas)
+		{
+			area->notifyWindowResized(window->getWidth(), window->getHeight());
+		}
+	}
+
 	void GUIWidget::render(RenderContext& renderContext) const
 	{
 		// Mesh is re-created every frame. There might be a better approach that only recreates it upon change,

+ 8 - 8
BansheeEngine/Source/BsGUIWindowFrame.cpp

@@ -16,8 +16,8 @@ namespace BansheeEngine
 		return name;
 	}
 
-	GUIWindowFrame::GUIWindowFrame(GUIWidget& parent, const GUI_LAYOUT_OPTIONS* layoutOptions)
-		:GUIElement(parent)
+	GUIWindowFrame::GUIWindowFrame(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions)
+		:GUIElement(parent, layoutOptions)
 	{
 		const GUISkin* skin = parent.getGUISkin();
 
@@ -41,11 +41,6 @@ namespace BansheeEngine
 		mImageSprite->update(desc);
 
 		mBounds = mImageSprite->getBounds();
-
-		if(layoutOptions != nullptr)
-			mLayoutOptions = *layoutOptions;
-		else
-			mLayoutOptions = getDefaultLayoutOptions();
 	}
 
 	GUIWindowFrame::~GUIWindowFrame()
@@ -53,7 +48,12 @@ namespace BansheeEngine
 		CM_DELETE(mImageSprite, ImageSprite, PoolAlloc);
 	}
 
-	GUIWindowFrame* GUIWindowFrame::create(GUIWidget& parent, const GUI_LAYOUT_OPTIONS* layoutOptions)
+	GUIWindowFrame* GUIWindowFrame::create(GUIWidget& parent)
+	{
+		return CM_NEW(GUIWindowFrame, PoolAlloc) GUIWindowFrame(parent, getDefaultLayoutOptions());
+	}
+
+	GUIWindowFrame* GUIWindowFrame::create(GUIWidget& parent, const GUI_LAYOUT_OPTIONS& layoutOptions)
 	{
 		return CM_NEW(GUIWindowFrame, PoolAlloc) GUIWindowFrame(parent, layoutOptions);
 	}

+ 1 - 1
CamelotClient/CmEditorWindow.cpp

@@ -52,7 +52,7 @@ namespace BansheeEditor
 		GUIArea* backgroundArea = GUIArea::create(*mGUI, 0, 0, 0, 0, 0);
 		GUILayout& layout = backgroundArea->getLayout();
 		
-		mDbgLabel = GUILabel::create(*mGUI, "Testing test", renderWindowDesc.width);
+		mDbgLabel = GUILabel::create(*mGUI, "Testing test");
 		layout.addElement(mDbgLabel);
 
 		GUIArea* mainArea = GUIArea::create(*mGUI, 0, 0, 0, 0, 1);

+ 1 - 1
CamelotClient/CmTestTextSprite.cpp

@@ -30,7 +30,7 @@ namespace CamelotFramework
 	{
 		setSkin(&EngineGUI::instance().getSkin());
 
-		GUILabel::create(*this, text, 400, 400, true, THA_Right, TVA_Bottom);
+		GUILabel::create(*this, text, THA_Right, TVA_Bottom, true);
 		GUIWindowFrame::create(*this);
 	}
 

+ 4 - 1
CamelotCore/Include/CmRenderWindow.h

@@ -29,6 +29,7 @@ THE SOFTWARE
 #include "CmPrerequisites.h"
 
 #include "CmRenderTarget.h"
+#include "boost/signal.hpp"
 
 namespace CamelotFramework
 {
@@ -129,7 +130,7 @@ namespace CamelotFramework
         @remarks
             You don't need to call this unless you created the window externally.
         */
-        virtual void windowMovedOrResized() {}
+        virtual void windowMovedOrResized();
 
         /** Reposition the window.
         */
@@ -175,6 +176,8 @@ namespace CamelotFramework
           */
         void setDeactivateOnFocusChange(bool deactivate);
 
+		mutable boost::signal<void(RenderWindow*)> onWindowMovedOrResized;
+		
 		virtual void destroy();
 
 		static RenderWindowPtr create(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow = nullptr);

+ 6 - 0
CamelotCore/Source/CmRenderWindow.cpp

@@ -70,6 +70,12 @@ namespace CamelotFramework
         mAutoDeactivatedOnFocusChange = deactivate;
     }
 
+	void RenderWindow::windowMovedOrResized()
+	{
+		if(!onWindowMovedOrResized.empty())
+			onWindowMovedOrResized(this);
+	}
+
 	void RenderWindow::destroy()
 	{
 		RenderWindowManager::instance().windowDestroyed(this);

+ 2 - 0
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -342,6 +342,8 @@ namespace CamelotFramework
 			return;
 
 		_resizeSwapChainBuffers(width, height);
+
+		RenderWindow::windowMovedOrResized();
 	}
 
 	void D3D11RenderWindow::setActive(bool state)

+ 2 - 0
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -609,6 +609,8 @@ namespace CamelotFramework
 			return;
 	
 		updateWindowRect();
+
+		RenderWindow::windowMovedOrResized();
 	}
 
 	void D3D9RenderWindow::swapBuffers()

+ 1 - 1
CamelotGLRenderer/Source/CmWin32Window.cpp

@@ -614,7 +614,7 @@ namespace CamelotFramework {
 		mWidth = rc.right - rc.left;
 		mHeight = rc.bottom - rc.top;
 
-		// TODO - Notify viewports of resize
+		RenderWindow::windowMovedOrResized();
 	}
 
 	void Win32Window::swapBuffers()