Browse Source

Added GUI button and set up a working over/out event

Marko Pintera 12 years ago
parent
commit
599863fc64

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -150,6 +150,7 @@
     <ClInclude Include="Include\BsDebugDraw.h" />
     <ClInclude Include="Include\BsEngineGUI.h" />
     <ClInclude Include="Include\BsGUIArea.h" />
+    <ClInclude Include="Include\BsGUIButton.h" />
     <ClInclude Include="Include\BsGUILayoutOptions.h" />
     <ClInclude Include="Include\BsGUILayoutX.h" />
     <ClInclude Include="Include\BsGUILayout.h" />
@@ -187,6 +188,7 @@
     <ClCompile Include="Source\BsDebugDraw.cpp" />
     <ClCompile Include="Source\BsEngineGUI.cpp" />
     <ClCompile Include="Source\BsGUIArea.cpp" />
+    <ClCompile Include="Source\BsGUIButton.cpp" />
     <ClCompile Include="Source\BsGUIElement.cpp" />
     <ClCompile Include="Source\BsGUILabel.cpp" />
     <ClCompile Include="Source\BsGUILayout.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -141,6 +141,9 @@
     <ClInclude Include="Include\BsGUISpace.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsGUIButton.h">
+      <Filter>Header Files\GUI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -227,5 +230,8 @@
     <ClCompile Include="Source\BsGUILayoutY.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsGUIButton.cpp">
+      <Filter>Source Files\GUI</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 3 - 0
BansheeEngine/Include/BsEngineGUI.h

@@ -20,5 +20,8 @@ namespace BansheeEngine
 		static const UINT32 DefaultFontSize;
 
 		static const CM::String WindowFramePrimaryTexture;
+
+		static const CM::String ButtonNormalTex;
+		static const CM::String ButtonHoverTex;
 	};
 }

+ 57 - 0
BansheeEngine/Include/BsGUIButton.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsGUIElement.h"
+#include "BsImageSprite.h"
+
+namespace BansheeEngine
+{
+	class BS_EXPORT GUIButton : public GUIElement
+	{
+	public:
+		static const CM::String& getGUITypeName();
+
+		static GUIButton* create(GUIWidget& parent);
+		static GUIButton* create(GUIWidget& parent, const GUILayoutOptions& layoutOptions);
+	protected:
+		~GUIButton();
+
+		/**
+		 * @copydoc GUIElement::getNumRenderElements()
+		 */
+		virtual UINT32 getNumRenderElements() const;
+
+		/**
+		 * @copydoc GUIElement::getMaterial()
+		 */
+		virtual const CM::HMaterial& getMaterial(UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::getNumQuads()
+		 */
+		virtual UINT32 getNumQuads(UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::fillBuffer()
+		 */
+		virtual void fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, 
+			UINT32 maxNumQuads, UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const;
+
+		/**
+		 * @copydoc GUIElement::updateRenderElementsInternal()
+		 */
+		virtual void updateRenderElementsInternal();
+
+		virtual UINT32 _getOptimalWidth() const;
+		virtual UINT32 _getOptimalHeight() const;
+
+		static const GUILayoutOptions& getDefaultLayoutOptions();
+	private:
+		ImageSprite* mImageSprite;
+		IMAGE_SPRITE_DESC mDesc;
+
+		GUIButton(GUIWidget& parent, const GUILayoutOptions& layoutOptions);
+
+		virtual bool mouseEvent(const GUIMouseEvent& ev);
+	};
+}

+ 21 - 1
BansheeEngine/Source/BsEngineGUI.cpp

@@ -3,6 +3,7 @@
 
 #include "BsGUILabel.h"
 #include "BsGUIWindowFrame.h"
+#include "BsGUIButton.h"
 #include "BsSpriteTexture.h"
 
 #include "CmFont.h"
@@ -17,7 +18,10 @@ namespace BansheeEngine
 	const String EngineGUI::DefaultFontPath = "C:\\arial.ttf";
 	const UINT32 EngineGUI::DefaultFontSize = 12;
 
-	const CM::String EngineGUI::WindowFramePrimaryTexture = "C:\\WindowFrame.psd";
+	const String EngineGUI::WindowFramePrimaryTexture = "C:\\WindowFrame.psd";
+
+	const String EngineGUI::ButtonNormalTex = "C:\\Projects\\BansheeEngine\\Data\\Editor\\Skin\\ButtonNormal.psd";
+	const String EngineGUI::ButtonHoverTex = "C:\\Projects\\BansheeEngine\\Data\\Editor\\Skin\\ButtonHover.psd";
 
 	EngineGUI::EngineGUI()
 	{
@@ -59,6 +63,22 @@ namespace BansheeEngine
 		windowFrameStyle.border.bottom = 1;
 
 		mSkin.setStyle(GUIWindowFrame::getGUITypeName(), windowFrameStyle);
+
+		// Button
+		HTexture buttonNormalTex = static_resource_cast<Texture>(Importer::instance().import(ButtonNormalTex));
+		HTexture buttonHoverTex = static_resource_cast<Texture>(Importer::instance().import(ButtonHoverTex));
+		buttonNormalTex.waitUntilLoaded();
+		buttonHoverTex.waitUntilLoaded();
+
+		GUIElementStyle buttonStyle;
+		buttonStyle.normal.texture = SpriteTexturePtr(CM_NEW(SpriteTexture, PoolAlloc) SpriteTexture(buttonNormalTex), &MemAllocDeleter<SpriteTexture, PoolAlloc>::deleter);
+		buttonStyle.hover.texture = SpriteTexturePtr(CM_NEW(SpriteTexture, PoolAlloc) SpriteTexture(buttonHoverTex), &MemAllocDeleter<SpriteTexture, PoolAlloc>::deleter);
+		buttonStyle.border.left = 5;
+		buttonStyle.border.right = 5;
+		buttonStyle.border.top = 5;
+		buttonStyle.border.bottom = 5;
+
+		mSkin.setStyle(GUIButton::getGUITypeName(), buttonStyle);
 	}
 
 }

+ 146 - 0
BansheeEngine/Source/BsGUIButton.cpp

@@ -0,0 +1,146 @@
+#include "BsGUIButton.h"
+#include "BsImageSprite.h"
+#include "BsGUIWidget.h"
+#include "BsGUISkin.h"
+#include "BsSpriteTexture.h"
+#include "BsGUILayoutOptions.h"
+#include "BsGUIMouseEvent.h"
+#include "CmTexture.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	const String& GUIButton::getGUITypeName()
+	{
+		static String name = "Button";
+		return name;
+	}
+
+	GUIButton::GUIButton(GUIWidget& parent, const GUILayoutOptions& layoutOptions)
+		:GUIElement(parent, layoutOptions)
+	{
+		const GUISkin* skin = parent.getGUISkin();
+
+		mStyle = skin->getStyle(getGUITypeName());
+		mImageSprite = CM_NEW(ImageSprite, PoolAlloc) ImageSprite();
+
+		mDesc.texture = mStyle->normal.texture;
+
+		if(mDesc.texture != nullptr)
+		{
+			mDesc.width = mDesc.texture->getTexture()->getWidth();
+			mDesc.height = mDesc.texture->getTexture()->getHeight();
+		}
+
+		mDesc.borderLeft = mStyle->border.left;
+		mDesc.borderRight = mStyle->border.right;
+		mDesc.borderTop = mStyle->border.top;
+		mDesc.borderBottom = mStyle->border.bottom;
+	}
+
+	GUIButton::~GUIButton()
+	{
+		CM_DELETE(mImageSprite, ImageSprite, PoolAlloc);
+	}
+
+	GUIButton* GUIButton::create(GUIWidget& parent)
+	{
+		return CM_NEW(GUIButton, PoolAlloc) GUIButton(parent, getDefaultLayoutOptions());
+	}
+
+	GUIButton* GUIButton::create(GUIWidget& parent, const GUILayoutOptions& layoutOptions)
+	{
+		return CM_NEW(GUIButton, PoolAlloc) GUIButton(parent, layoutOptions);
+	}
+
+	UINT32 GUIButton::getNumRenderElements() const
+	{
+		return mImageSprite->getNumRenderElements();
+	}
+
+	const HMaterial& GUIButton::getMaterial(UINT32 renderElementIdx) const
+	{
+		return mImageSprite->getMaterial(renderElementIdx);
+	}
+
+	UINT32 GUIButton::getNumQuads(UINT32 renderElementIdx) const
+	{
+		return mImageSprite->getNumQuads(renderElementIdx);
+	}
+
+	void GUIButton::updateRenderElementsInternal()
+	{		
+		mDesc.offset = mOffset;
+		mDesc.width = mWidth;
+		mDesc.height = mHeight;
+		mDesc.clipRect = mClipRect;
+
+		mImageSprite->update(mDesc);
+		mBounds = mImageSprite->getBounds();
+	}
+
+	UINT32 GUIButton::_getOptimalWidth() const
+	{
+		if(mDesc.texture != nullptr)
+		{
+			return mDesc.texture->getTexture()->getWidth();
+		}
+
+		return 0;
+	}
+
+	UINT32 GUIButton::_getOptimalHeight() const
+	{
+		if(mDesc.texture != nullptr)
+		{
+			return mDesc.texture->getTexture()->getHeight();
+		}
+
+		return 0;
+	}
+
+	void GUIButton::fillBuffer(UINT8* vertices, UINT8* uv, UINT32* indices, UINT32 startingQuad, UINT32 maxNumQuads, 
+		UINT32 vertexStride, UINT32 indexStride, UINT32 renderElementIdx) const
+	{
+		mImageSprite->fillBuffer(vertices, uv, indices, startingQuad, maxNumQuads, vertexStride, indexStride, renderElementIdx);
+	}
+
+	const GUILayoutOptions& GUIButton::getDefaultLayoutOptions()
+	{
+		static GUILayoutOptions layoutOptions;
+		static bool layoutOptionsInitialized = false;
+
+		if(!layoutOptionsInitialized)
+		{
+			layoutOptions.fixedWidth = false;
+			layoutOptions.fixedHeight = false;
+
+			layoutOptionsInitialized = true;
+		}
+
+		return layoutOptions;
+	}
+
+	bool GUIButton::mouseEvent(const GUIMouseEvent& ev)
+	{
+		if(ev.getType() == GUIMouseEventType::MouseOver)
+		{
+			mDesc.texture = mStyle->normal.texture;
+			markAsDirty();
+			// TODO - What happens when a texture is not set?
+			// 
+			return true;
+		}
+		else if(ev.getType() == GUIMouseEventType::MouseOut)
+		{
+			mDesc.texture = mStyle->hover.texture;
+			markAsDirty();
+			// TODO - What happens when a texture is not set?
+
+			return true;
+		}
+		
+		return false;
+	}
+}

+ 1 - 3
BansheeEngine/Source/BsGUIManager.cpp

@@ -409,7 +409,7 @@ namespace BansheeEngine
 #endif
 		GUIWidget* widgetInFocus = nullptr;
 		GUIElement* topMostElement = nullptr;
-		UINT32 topMostDepth = std::numeric_limits<UINT32>::max();
+		INT32 topMostDepth = std::numeric_limits<INT32>::max();
 
 		for(auto& widget : mWidgets)
 		{
@@ -430,8 +430,6 @@ namespace BansheeEngine
 			screenPos = Cursor::getWindowPosition(*window);
 			Vector4 vecScreenPos((float)screenPos.x, (float)screenPos.y, 0.0f, 1.0f);
 
-			GUIElement* topMostElement = nullptr;
-			INT32 topMostDepth = std::numeric_limits<INT32>::max();
 			for(auto& widget : mWidgets)
 			{
 				if(widget->inBounds(screenPos))

+ 3 - 1
CamelotClient/CmEditorWindow.cpp

@@ -7,6 +7,7 @@
 #include "BsGUIWidget.h"
 #include "BsGUILabel.h"
 #include "BsGUIWindowFrame.h"
+#include "BsGUIButton.h"
 #include "BsGUISkin.h"
 #include "BsGUILayout.h"
 #include "BsOverlayManager.h"
@@ -65,7 +66,8 @@ namespace BansheeEditor
 		GUIFlexibleSpace& space3 = otherLayout.addFlexibleSpace();
 		otherLayout.addElement(GUIWindowFrame::create(*mGUI, GUILayoutOptions::expandableX(20, 20)));
 		//GUIFixedSpace& space2 = otherLayout.addSpace(10);
-		otherLayout.addElement(GUIWindowFrame::create(*mGUI));
+		otherLayout.addElement(GUIButton::create(*mGUI));
+		//otherLayout.addElement(GUIWindowFrame::create(*mGUI));
 	}
 
 	EditorWindow::~EditorWindow()

+ 1 - 4
TODO.txt

@@ -22,10 +22,7 @@ I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 
 IMMEDIATE:
- - Implement GUILayoutY
-
-Test nested elements
-Test with flexible space, left center and right
+ - Test GUILayoutY and nested layouts
 
 -----------