changeset 21:b4dc5d674e22

Added GUI event system and some support data structures
author koryspansel
date Thu, 15 Sep 2011 18:42:12 -0700
parents 4e9b5299ffdc
children 502ed0a0059a
files LightClone.smp LightClone/LightClone.vcproj LightClone/Source/ArrayList.h LightClone/Source/FixedString.h LightClone/Source/GuiButton.cpp LightClone/Source/GuiButton.h LightClone/Source/GuiElement.cpp LightClone/Source/GuiElement.h LightClone/Source/GuiEvent.cpp LightClone/Source/GuiEvent.h LightClone/Source/GuiEventMap.cpp LightClone/Source/GuiEventMap.h LightClone/Source/GuiFunctor.h LightClone/Source/GuiImage.cpp LightClone/Source/GuiImage.h LightClone/Source/GuiInterface.cpp LightClone/Source/HashMap.h LightClone/Source/World.cpp LightClone/Source/World.h
diffstat 19 files changed, 849 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
Binary file LightClone.smp has changed
--- a/LightClone/LightClone.vcproj	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/LightClone.vcproj	Thu Sep 15 18:42:12 2011 -0700
@@ -253,6 +253,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\GuiEvent.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\Source\GuiEventMap.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\GuiImage.cpp"
 				>
 			</File>
@@ -387,6 +395,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\FixedString.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\GraphicsDevice.h"
 				>
 			</File>
@@ -403,6 +415,18 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\GuiEvent.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Source\GuiEventMap.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Source\GuiFunctor.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\GuiImage.h"
 				>
 			</File>
@@ -415,6 +439,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Source\HashMap.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Source\InputManager.h"
 				>
 			</File>
--- a/LightClone/Source/ArrayList.h	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/ArrayList.h	Thu Sep 15 18:42:12 2011 -0700
@@ -48,7 +48,7 @@
 	/*
 	 * Add
 	 */
-	ErrorCode Add(Type& kValue)
+	ErrorCode Add(Type kValue)
 	{
 		ErrorCode eCode = Resize(nSize + 1);
 		if(eCode == Error_Success)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/FixedString.h	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,152 @@
+/*
+ * FixedString
+ */
+
+#ifndef __FIXEDSTRING_H__
+#define __FIXEDSTRING_H__
+
+#include "Types.h"
+#include <string.h>
+
+/*
+ * FixedString
+ */
+template<uint32 Size = 64>
+class FixedString
+{
+public:
+
+	/*
+	 * MaximumLength
+	 */
+	static const uint32 MaximumLength = Size;
+
+private:
+
+	/*
+	 * kString
+	 */
+	char kString[Size];
+
+	/*
+	 * nLength
+	 */
+	uint32 nLength;
+
+public:
+
+	/*
+	 * FixedString
+	 */
+	FixedString() : nLength(0)
+	{
+		memset(kString, 0, sizeof(kString));
+	}
+
+	/*
+	 * FixedString
+	 */
+	FixedString(const char* pValue) : nLength(0)
+	{
+		while(*pValue)
+		{
+			kString[nLength++] = *pValue++;
+		}
+
+		kString[nLength] = 0;
+	}
+
+	/*
+	 * FixedString
+	 */
+	FixedString(const FixedString& kOther) : nLength(kOther.nLength)
+	{
+		for(uint32 i = 0 ; i < kOther.nLength; ++i)
+		{
+			kString[i] = kOther.kString[i];
+		}
+
+		kString[nLength] = 0;
+	}
+
+	/*
+	 * operator =
+	 */
+	const FixedString& operator =(const FixedString& kOther)
+	{
+		nLength = kOther.nLength;
+
+		for(uint32 i = 0 ; i < kOther.nLength; ++i)
+		{
+			kString[i] = kOther.kString[i];
+		}
+
+		kString[nLength] = 0;
+	}
+
+	/*
+	 * Length
+	 */
+	uint32 Length() const
+	{
+		return nLength;
+	}
+
+	/*
+	 * operator char*
+	 */
+	operator char*()
+	{
+		return kString;
+	}
+
+	/*
+	 * operator const char*
+	 */
+	operator const char*() const
+	{
+		return kString;
+	}
+};
+
+/*
+ * FixedStringHash
+ */
+struct FixedStringHash
+{
+	/*
+	 * operator()
+	 */
+	uint32 operator()(const FixedString<>& kString)
+	{
+		uint32 nHash = 5381;
+
+		const char* pString = (const char*)kString;
+		while(*pString)
+		{
+			nHash = ((nHash << 5) + nHash) + *pString++;
+		}
+
+		return nHash;
+	}
+};
+
+/*
+ * operator ==
+ */
+template<uint32 Size>
+bool operator ==(const FixedString<Size>& kStringA, const FixedString<Size>& kStringB)
+{
+	return kStringA.Length() == kStringB.Length() && strcmp(kStringA, kStringB) == 0;
+}
+
+/*
+ * operator !=
+ */
+template<uint32 Size>
+bool operator !=(const FixedString<Size>& kStringA, const FixedString<Size>& kStringB)
+{
+	return kStringA.Length() != kStringB.Length() || strcmp(kStringA, kStringB) != 0;
+}
+
+#endif //__FIXEDSTRING_H__
--- a/LightClone/Source/GuiButton.cpp	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiButton.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -6,24 +6,34 @@
 #include "VertexTypes.h"
 
 /*
+ * EventClick
+ */
+const char* GuiButton::EventClick = "GuiButton:Click";
+
+/*
  * GuiButton
  */
-GuiButton::GuiButton()
+GuiButton::GuiButton() : nState(GuiButtonState_Normal), pEffect(NULL), pVertexBuffer(NULL)
 {
+	memset(pTexture, 0, sizeof(pTexture));
 }
 
 /*
  * Initialize
  */
-ErrorCode GuiButton::Initialize(ResourceManager* pResourceManager)
+ErrorCode GuiButton::Initialize(ResourceManager* pManager)
 {
-	ErrorCode eCode = pResourceManager->CreateEffectFromFile("Data\\Shaders\\TexturedQuad.fx", &pEffect);
+	ErrorCode eCode = pManager->CreateEffectFromFile("Data\\Shaders\\TexturedQuad.fx", &pEffect);
 	if(eCode == Error_Success)
 	{
-		eCode = pResourceManager->CreateVertexBuffer(6 * sizeof(Vertex::Quad), D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED, &pVertexBuffer);
+		eCode = pManager->CreateVertexBuffer(6 * sizeof(Vertex::Quad), D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED, &pVertexBuffer);
 		if(eCode == Error_Success)
 		{
 			eCode = SetupVertexBuffer();
+			if(eCode == Error_Success)
+			{
+				pResourceManager = pManager;
+			}
 		}
 	}
 
@@ -71,20 +81,20 @@
 {
 	if(pTexture[nState])
 	{
+		uint32 nPasses = 0;
+
+		const float fOffsetX = -0.5f * ScreenSizeX;
+		const float fOffsetY = +0.5f * ScreenSizeY;
+
 		const D3DXVECTOR4 kColorVector(1.0f, 1.0f, 1.0f, 1.0f);
 
-		D3DSURFACE_DESC kDescriptor;
-		pTexture[nState]->GetLevelDesc(0, &kDescriptor);
-
-		const float fX = ScreenSizeX - (float)kDescriptor.Width;
-		const float fY = 0.0f;
+		kContext.ApplyCameraToEffect(kCamera, pEffect);
 
 		D3DXMATRIX kScale;
-		D3DXMatrixScaling(&kScale, (float)kDescriptor.Width, (float)kDescriptor.Height, 1.0f);
+		D3DXMatrixScaling(&kScale, kDimensions.x, kDimensions.y, 1.0f);
 
 		D3DXMATRIX kTranslate;
-		//D3DXMatrixTranslation(&kTranslate, -0.5f * ScreenSizeX + fX + 0.5f, 0.5f * ScreenSizeY - fY + 0.5f, 0.0f);
-		//D3DXMatrixTranslation(
+		D3DXMatrixTranslation(&kTranslate, fOffsetX + kPosition.x + 0.5f, fOffsetY - kPosition.y + 0.5f, 0.0f);
 
 		D3DXMATRIX kWorldMatrix;
 		D3DXMatrixMultiply(&kWorldMatrix, &kScale, &kTranslate);
@@ -92,13 +102,69 @@
 		pEffect->SetMatrix(pEffect->GetParameterByName(NULL, "kWorld"), &kWorldMatrix);
 		pEffect->SetVector(pEffect->GetParameterByName(NULL, "kColor"), &kColorVector);
 		pEffect->SetTexture(pEffect->GetParameterByName(NULL, "kTexture"), pTexture[nState]);
-		pEffect->CommitChanges();
+
+		pEffect->SetTechnique(pEffect->GetTechnique(0));
+		pEffect->Begin(&nPasses, 0);
+		pEffect->BeginPass(0);
 
 		kContext.DrawTriangles(Vertex::Quad::Declaration, pVertexBuffer, sizeof(Vertex::Quad), TrianglesPerFace);
+
+		pEffect->EndPass();
+		pEffect->End();
 	}
 }
 
 /*
+ * SetTexture
+ */
+ErrorCode GuiButton::SetTexture(uint32 nState, const char* pName, bool bResize)
+{
+	ErrorCode eCode = Error_Fail;
+
+	if(nState < GuiButtonState_Count)
+	{
+		if(pTexture[nState])
+		{
+			pTexture[nState]->Release();
+			pTexture[nState] = NULL;
+		}
+
+		eCode = pResourceManager->CreateTextureFromFile(pName, &pTexture[nState]);
+		if(eCode == Error_Success)
+		{
+			if(bResize)
+			{
+				D3DSURFACE_DESC kDescriptor;
+				pTexture[nState]->GetLevelDesc(0, &kDescriptor);
+
+				kDimensions.x = (float)kDescriptor.Width;
+				kDimensions.y = (float)kDescriptor.Height;
+			}
+		}
+	}
+
+	return eCode;
+}
+
+/*
+ * OnMouseDown
+ */
+void GuiButton::OnMouseDown(uint32 nButton, float fX, float fY)
+{
+	GuiEventArguments kArguments;
+	kArguments.pSource = this;
+
+	Fire(EventClick, kArguments);
+}
+
+/*
+ * OnMouseUp
+ */
+void GuiButton::OnMouseUp(uint32 nButton, float fX, float fY)
+{
+}
+
+/*
  * SetupVertexBuffer
  */
 ErrorCode GuiButton::SetupVertexBuffer()
@@ -111,12 +177,12 @@
 		return Error_Fail;
 	}
 
-	pVertices[0]	= Vertex::Quad(+0.0f, -1.0f, 1.0f, 0.0f, 1.0f);
-	pVertices[1]	= Vertex::Quad(+0.0f, +0.0f, 1.0f, 0.0f, 0.0f);
-	pVertices[2]	= Vertex::Quad(+1.0f, +0.0f, 1.0f, 1.0f, 0.0f);
-	pVertices[3]	= Vertex::Quad(+0.0f, -1.0f, 1.0f, 0.0f, 1.0f);
-	pVertices[4]	= Vertex::Quad(+1.0f, +0.0f, 1.0f, 1.0f, 0.0f);
-	pVertices[5]	= Vertex::Quad(+1.0f, -1.0f, 1.0f, 1.0f, 1.0f);
+	pVertices[0] = Vertex::Quad(+0.0f, -1.0f, 1.0f, 0.0f, 1.0f);
+	pVertices[1] = Vertex::Quad(+0.0f, +0.0f, 1.0f, 0.0f, 0.0f);
+	pVertices[2] = Vertex::Quad(+1.0f, +0.0f, 1.0f, 1.0f, 0.0f);
+	pVertices[3] = Vertex::Quad(+0.0f, -1.0f, 1.0f, 0.0f, 1.0f);
+	pVertices[4] = Vertex::Quad(+1.0f, +0.0f, 1.0f, 1.0f, 0.0f);
+	pVertices[5] = Vertex::Quad(+1.0f, -1.0f, 1.0f, 1.0f, 1.0f);
 
 	pVertexBuffer->Unlock();
 
--- a/LightClone/Source/GuiButton.h	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiButton.h	Thu Sep 15 18:42:12 2011 -0700
@@ -23,8 +23,22 @@
 /*
  * GuiButton
  */
-class GuiButton
+class GuiButton : public GuiElement
 {
+public:
+
+	/*
+	 * EventClick
+	 */
+	static const char* EventClick;
+
+private:
+
+	/*
+	 * pResourceManager
+	 */
+	ResourceManager* pResourceManager;
+
 	/*
 	 * nState
 	 */
@@ -55,7 +69,7 @@
 	/*
 	 * Initialize
 	 */
-	virtual ErrorCode Initialize(ResourceManager* pResourceManager);
+	virtual ErrorCode Initialize(ResourceManager* pManager);
 
 	/*
 	 * Terminate
@@ -72,6 +86,21 @@
 	 */
 	virtual void Render(RenderContext& kContext, Camera& kCamera);
 
+	/*
+	 * SetTexture
+	 */
+	ErrorCode SetTexture(uint32 nState, const char* pName, bool bResize = false);
+
+	/*
+	 * OnMouseDown
+	 */
+	virtual void OnMouseDown(uint32 nButton, float fX, float fY);
+
+	/*
+	 * OnMouseUp
+	 */
+	virtual void OnMouseUp(uint32 nButton, float fX, float fY);
+
 private:
 
 	/*
--- a/LightClone/Source/GuiElement.cpp	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiElement.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -232,6 +232,13 @@
 }
 
 /*
+ * OnMouseMove
+ */
+void GuiElement::OnMouseMove(float fX, float fY)
+{
+}
+
+/*
  * OnDrag
  */
 void GuiElement::OnDrag(float fX, float fY)
--- a/LightClone/Source/GuiElement.h	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiElement.h	Thu Sep 15 18:42:12 2011 -0700
@@ -10,11 +10,12 @@
 #include "RenderContext.h"
 #include "Camera.h"
 #include "ArrayList.h"
+#include "GuiEventMap.h"
 
 /*
  * GuiElement
  */
-class GuiElement
+class GuiElement : private GuiEventMap
 {
 public:
 
@@ -163,6 +164,11 @@
 	virtual void OnMouseUp(uint32 nButton, float fX, float fY);
 
 	/*
+	 * OnMouseMove
+	 */
+	virtual void OnMouseMove(float fX, float fY);
+
+	/*
 	 * OnDrag
 	 */
 	virtual void OnDrag(float fX, float fY);
@@ -171,6 +177,16 @@
 	 * OnDrop
 	 */
 	virtual void OnDrop(GuiElement* pSource, float fX, float fY);
+
+	/*
+	 * Subscribe
+	 */
+	using GuiEventMap::Subscribe;
+
+	/*
+	 * Fire
+	 */
+	using GuiEventMap::Fire;
 };
 
 #endif //__GUIELEMENT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/GuiEvent.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,36 @@
+/*
+ * GuiEvent
+ */
+
+#include "GuiEvent.h"
+
+/*
+ * GuiEvent
+ */
+GuiEvent::GuiEvent(const char* pEventName) : kName(pEventName)
+{
+}
+
+/*
+ * ~GuiEvent
+ */
+GuiEvent::~GuiEvent()
+{
+	for(uint32 i = 0; i < kSubscriptions.Size(); ++i)
+	{
+		delete kSubscriptions[i];
+	}
+
+	kSubscriptions.Clear();
+}
+
+/*
+ * Fire
+ */
+void GuiEvent::Fire(GuiEventArguments& kArguments)
+{
+	for(uint32 i = 0; i < kSubscriptions.Size(); ++i)
+	{
+		(*kSubscriptions[i])(kArguments);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/GuiEvent.h	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,78 @@
+/*
+ * GuiEvent
+ */
+
+#ifndef __GUIEVENT_H__
+#define __GUIEVENT_H__
+
+#include "Core.h"
+#include "FixedString.h"
+#include "GuiFunctor.h"
+
+/*
+ * GuiElement
+ */
+class GuiElement;
+
+/*
+ * GuiEventArguments
+ */
+struct GuiEventArguments
+{
+	/*
+	 * pSource
+	 */
+	GuiElement* pSource;
+};
+
+/*
+ * GuiEvent
+ */
+class GuiEvent
+{
+	/*
+	 * kName
+	 */
+	FixedString<> kName;
+
+	/*
+	 * kSubscriptions
+	 */
+	GuiFunctor::List kSubscriptions;
+
+public:
+
+	/*
+	 * GuiEvent
+	 */
+	GuiEvent(const char* pEventName);
+
+	/*
+	 * ~GuiEvent
+	 */
+	~GuiEvent();
+
+	/*
+	 * Subscribe
+	 */
+	ErrorCode Subscribe(void (*pFunction)(GuiEventArguments&))
+	{
+		return kSubscriptions.Add(new GuiFunction(pFunction));
+	}
+
+	/*
+	 * Subscribe
+	 */
+	template<typename Type>
+	ErrorCode Subscribe(void (Type::*pFunction)(GuiEventArguments&), Type* pInstance)
+	{
+		return kSubscriptions.Add(new GuiMethod<Type>(pFunction, pInstance));
+	}
+
+	/*
+	 * Fire
+	 */
+	void Fire(GuiEventArguments&);
+};
+
+#endif //__GUIEVENT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/GuiEventMap.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,46 @@
+/*
+ * GuiEventMap
+ */
+
+#include "GuiEventMap.h"
+
+/* 
+ * GuiEventMap
+ */
+GuiEventMap::GuiEventMap()
+{
+}
+
+/*
+ * Fire
+ */
+void GuiEventMap::Fire(const char* pName, GuiEventArguments& kArguments)
+{
+	GuiEvent* pEvent = GetEvent(pName);
+	if(pEvent)
+	{
+		pEvent->Fire(kArguments);
+	}
+}
+
+/*
+ * GetEvent
+ */
+GuiEvent* GuiEventMap::GetEvent(const char* pName, bool bAdd)
+{
+	GuiEvent** pEvent = kMap.Find(FixedString<>(pName));
+	if(!pEvent)
+	{
+		if(bAdd)
+		{
+			pEvent = kMap.Add(FixedString<>(pName));
+			if(pEvent)
+			{
+				*pEvent = new GuiEvent(pName);
+			}
+		}
+	}
+
+	return pEvent ? *pEvent : NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/GuiEventMap.h	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,71 @@
+/*
+ * GuiEventMap
+ */
+
+#ifndef __GUIEVENTMAP_H__
+#define __GUIEVENTMAP_H__
+
+#include "Core.h"
+#include "GuiEvent.h"
+#include "HashMap.h"
+
+/*
+ * GuiEventMap
+ */
+class GuiEventMap
+{
+	/*
+	 * kMap
+	 */
+	HashMap<FixedString<>, GuiEvent*, FixedStringHash> kMap;
+
+public:
+
+	/* 
+	 * GuiEventMap
+	 */
+	GuiEventMap();
+
+	/*
+	 * Subscribe
+	 */
+	ErrorCode Subscribe(const char* pName, void (*pFunction)(GuiEventArguments&))
+	{
+		GuiEvent* pEvent = GetEvent(pName, true);
+		if(pEvent)
+		{
+			return pEvent->Subscribe(pFunction), Error_Success;
+		}
+
+		return Error_Fail;
+	}
+
+	/*
+	 * Subscribe
+	 */
+	template<typename Type>
+	ErrorCode Subscribe(const char* pName, void (Type::*pFunction)(GuiEventArguments&), Type* pInstance)
+	{
+		GuiEvent* pEvent = GetEvent(pName, true);
+		if(pEvent)
+		{
+			return pEvent->Subscribe(pFunction, pInstance), Error_Success;
+		}
+
+		return Error_Fail;
+	}
+
+	/*
+	 * Fire
+	 */
+	void Fire(const char* pEvent, GuiEventArguments& kArguments);
+
+private:
+
+	/*
+	 * GetEvent
+	 */
+	GuiEvent* GetEvent(const char* pName, bool bAdd = false);
+};
+
+#endif //__GUIEVENTMAP_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/GuiFunctor.h	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,115 @@
+/*
+ * GuiFunctor
+ */
+
+#ifndef __GUIFUNCTOR_H__
+#define __GUIFUNCTOR_H__
+
+#include "Types.h"
+#include "ArrayList.h"
+
+/*
+ * GuiEventArguments
+ */
+struct GuiEventArguments;
+
+/*
+ * GuiFunctor
+ */
+class GuiFunctor
+{
+public:
+
+	/*
+	 * List
+	 */
+	typedef ArrayList<GuiFunctor*> List;
+
+public:
+
+	/*
+	 * ~GuiFunctor
+	 */
+	virtual ~GuiFunctor()
+	{
+	}
+
+	/*
+	 * operator ()
+	 */
+	virtual void operator()(GuiEventArguments&) = 0;
+};
+
+/*
+ * GuiFunction
+ */
+class GuiFunction : public GuiFunctor
+{
+	/*
+	 * FunctorType
+	 */
+	typedef void (*FunctorType)(GuiEventArguments&);
+
+	/*
+	 * pFunctor
+	 */
+	FunctorType pFunctor;
+
+public:
+
+	/*
+	 * GuiFunction
+	 */
+	GuiFunction(FunctorType pFunction) : pFunctor(pFunction)
+	{
+	}
+
+	/*
+	 * operator ()
+	 */
+	virtual void operator()(GuiEventArguments& kArguments)
+	{
+		(*pFunctor)(kArguments);
+	}
+};
+
+/*
+ * GuiMethod
+ */
+template <typename Object>
+class GuiMethod : public GuiFunctor
+{
+	/*
+	 * FunctorType
+	 */
+	typedef void (Object::*FunctorType)(GuiEventArguments&);
+
+	/*
+	 * pFunctor
+	 */
+	FunctorType pFunctor;
+
+	/*
+	 * pObject
+	 */
+	Object* pObject;
+
+public:
+
+	/*
+	 * GuiMethod
+	 */
+	GuiMethod(FunctorType pMethod, Object* pInstance) : pFunctor(pMethod), pObject(pInstance)
+	{
+	}
+
+	/*
+	 * operator()
+	 */
+	void operator()(GuiEventArguments& kArguments)
+	{
+		(pObject->*pFunctor)(kArguments);
+	}
+};
+
+#endif //__GUIFUNCTOR_H__
--- a/LightClone/Source/GuiImage.cpp	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiImage.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -79,10 +79,6 @@
 
 		kContext.ApplyCameraToEffect(kCamera, pEffect);
 
-		pEffect->SetTechnique(pEffect->GetTechnique(0));
-		pEffect->Begin(&nPasses, 0);
-		pEffect->BeginPass(0);
-
 		D3DXMATRIX kScale;
 		D3DXMatrixScaling(&kScale, kDimensions.x, kDimensions.y, 1.0f);
 
@@ -95,7 +91,10 @@
 		pEffect->SetMatrix(pEffect->GetParameterByName(NULL, "kWorld"), &kWorldMatrix);
 		pEffect->SetVector(pEffect->GetParameterByName(NULL, "kColor"), &kColorVector);
 		pEffect->SetTexture(pEffect->GetParameterByName(NULL, "kTexture"), pTexture);
-		pEffect->CommitChanges();
+
+		pEffect->SetTechnique(pEffect->GetTechnique(0));
+		pEffect->Begin(&nPasses, 0);
+		pEffect->BeginPass(0);
 
 		kContext.DrawTriangles(Vertex::Quad::Declaration, pVertexBuffer, sizeof(Vertex::Quad), TrianglesPerFace);
 
@@ -107,7 +106,7 @@
 /*
  * SetTexture
  */
-ErrorCode GuiImage::SetTexture(const char* pName)
+ErrorCode GuiImage::SetTexture(const char* pName, bool bResize)
 {
 	if(pTexture)
 	{
@@ -115,7 +114,20 @@
 		pTexture = NULL;
 	}
 
-	return pResourceManager->CreateTextureFromFile(pName, &pTexture);
+	ErrorCode eCode = pResourceManager->CreateTextureFromFile(pName, &pTexture);
+	if(eCode == Error_Success)
+	{
+		if(bResize)
+		{
+			D3DSURFACE_DESC kDescriptor;
+			pTexture->GetLevelDesc(0, &kDescriptor);
+
+			kDimensions.x = (float)kDescriptor.Width;
+			kDimensions.y = (float)kDescriptor.Height;
+		}
+	}
+
+	return eCode;
 }
 
 /*
--- a/LightClone/Source/GuiImage.h	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiImage.h	Thu Sep 15 18:42:12 2011 -0700
@@ -63,7 +63,7 @@
 	/*
 	 * SetTexture
 	 */
-	ErrorCode SetTexture(const char* pName);
+	ErrorCode SetTexture(const char* pName, bool bResize = false);
 
 private:
 
--- a/LightClone/Source/GuiInterface.cpp	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/GuiInterface.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -58,9 +58,11 @@
 
 	if(pCursor)
 	{
+		/*
 		char kBuffer[128];
-		sprintf(kBuffer, "<%0.2f, %0.2f>\n", fX, fY);
+		sprintf_s(kBuffer, "<%0.2f, %0.2f>\n", fX, fY);
 		OutputDebugStringA(kBuffer);
+		*/
 
 		pCursor->SetPosition(fX, fY);
 		pCursor->Update(fElapsed);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LightClone/Source/HashMap.h	Thu Sep 15 18:42:12 2011 -0700
@@ -0,0 +1,135 @@
+/*
+ * HashMap
+ */
+
+#ifndef __HASHMAP_H__
+#define __HASHMAP_H__
+
+#include "Types.h"
+
+/*
+ * DefaultHash
+ */
+template<typename Key>
+struct DefaultHash
+{
+	/*
+	 * operator()
+	 */
+	uint32 operator()(const Key& kKey)
+	{
+		return (uint32)(&kKey);
+	}
+};
+
+/*
+ * HashMap
+ */
+template<typename Key, typename Value, typename HashFunction = DefaultHash<Key>, uint32 Size = 97>
+class HashMap
+{
+	/*
+	 * Node
+	 */
+	struct Node
+	{
+		/*
+		 * kKey
+		 */
+		Key kKey;
+
+		/*
+		 * kValue
+		 */
+		Value kValue;
+
+		/*
+		 * pNext
+		 */
+		Node* pNext;
+
+		/*
+		 * Node
+		 */
+		Node(Key& kNodeKey) : kKey(kNodeKey), pNext(NULL)
+		{
+		}
+	};
+
+	/*
+	 * pTable
+	 */
+	Node* pTable[Size];
+
+	/*
+	 * kHash
+	 */
+	HashFunction kHash;
+
+public:
+
+	/*
+	 * HashMap
+	 */
+	HashMap() //: kHash()
+	{
+		for(uint32 i = 0; i < Size; ++i)
+		{
+			pTable[i] = 0;
+		}
+	}
+
+	/*
+	 * Add
+	 */
+	Value* Add(Key& kKey)
+	{
+		uint32 nSlot = GetSlot(kKey);
+
+		Node* pNode = new Node(kKey);
+		pNode->pNext = pTable[nSlot];
+		pTable[nSlot] = pNode;
+
+		return &pNode->kValue;
+	}
+
+	/*
+	 * Remove
+	 */
+	void Remove(const Key& kKey)
+	{
+	}
+
+	/*
+	 * Find
+	 */
+	Value* Find(const Key& kKey)
+	{
+		uint32 nSlot = GetSlot(kKey);
+
+		Node* pNode = pTable[nSlot];
+		while(pNode)
+		{
+			if(pNode->kKey == kKey)
+			{
+				return &pNode->kValue;
+			}
+			
+			++pNode;
+		}
+
+		return NULL;
+	}
+
+private:
+
+	/*
+	 * GetSlot
+	 */
+	uint32 GetSlot(const Key& kKey)
+	{
+		return kHash(kKey) % Size;
+	}
+};
+
+#endif //__HASHMAP_H__
--- a/LightClone/Source/World.cpp	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/World.cpp	Thu Sep 15 18:42:12 2011 -0700
@@ -6,6 +6,7 @@
 #include "VertexTypes.h"
 #include "GuiLabel.h"
 #include "GuiImage.h"
+#include "GuiButton.h"
 
 /*
  * World
@@ -295,12 +296,19 @@
 		GuiImage*
 		pImage = new GuiImage();
 		pImage->Initialize(pResourceManager);
-		pImage->SetTexture("Data\\Textures\\Slot.tga");
-		pImage->SetDimensions(48.0f, 48.0f);
-		pImage->SetPosition(0.5f * ScreenSizeX, 0.5f * ScreenSizeY);
+		pImage->SetTexture("Data\\Textures\\Background.tga", true);
+		pImage->SetPosition(0.5f * ScreenSizeX, 0.0f);
+
+		GuiButton*
+		pButton = new GuiButton();
+		pButton->Initialize(pResourceManager);
+		pButton->SetTexture(GuiButtonState_Normal, "Data\\Textures\\Play.tga", true);
+		pButton->SetPosition(0.5f * ScreenSizeX, 0.75f * ScreenSizeY);
+		pButton->Subscribe(GuiButton::EventClick, &World::OnClick, this);
 
 		//kInterface.Add(pLabel);
 		kInterface.Add(pImage);
+		kInterface.Add(pButton);
 
 		/*
 		//CodePanel* 
@@ -680,3 +688,11 @@
 		}
 	}
 }
+
+/*
+ * OnClick
+ */
+void World::OnClick(GuiEventArguments& kArguments)
+{
+	OutputDebugStringA("Button Clicked!\n");
+}
--- a/LightClone/Source/World.h	Thu Sep 15 13:28:10 2011 -0700
+++ b/LightClone/Source/World.h	Thu Sep 15 18:42:12 2011 -0700
@@ -230,6 +230,11 @@
 	 * ProcessInput
 	 */
 	void ProcessInput(float fElapsed);
+
+	/*
+	 * OnClick
+	 */
+	void OnClick(GuiEventArguments& kArguments);
 };
 
 #endif //__WORLD_H__