changeset 19:51718795f019

Adding event handling & drag and drop to GuiInterface
author koryspansel
date Thu, 15 Sep 2011 12:13:40 -0700
parents 33cb6979ac51
children 4e9b5299ffdc
files LightClone/LightClone.vcproj LightClone/Source/ArrayList.h LightClone/Source/CodePanel.cpp LightClone/Source/CodePanel.h LightClone/Source/EventSystem.cpp LightClone/Source/GuiContainer.cpp LightClone/Source/GuiContainer.h LightClone/Source/GuiElement.cpp LightClone/Source/GuiElement.h LightClone/Source/GuiInterface.cpp LightClone/Source/GuiInterface.h LightClone/Source/InputManager.h LightClone/Source/Interface.h LightClone/Source/World.cpp
diffstat 14 files changed, 298 insertions(+), 284 deletions(-) [+]
line wrap: on
line diff
--- a/LightClone/LightClone.vcproj	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/LightClone.vcproj	Thu Sep 15 12:13:40 2011 -0700
@@ -245,10 +245,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\Source\GuiContainer.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\Source\GuiElement.cpp"
 				>
 			</File>
@@ -395,10 +391,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\Source\GuiContainer.h"
-				>
-			</File>
-			<File
 				RelativePath=".\Source\GuiElement.h"
 				>
 			</File>
--- a/LightClone/Source/ArrayList.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/ArrayList.h	Thu Sep 15 12:13:40 2011 -0700
@@ -82,6 +82,27 @@
 	}
 
 	/*
+	 * Remove
+	 */
+	ErrorCode Remove(Type& kItem)
+	{
+		for(uint32 i = 0; i < nSize; ++i)
+		{
+			if(pList[i] == kItem)
+			{
+				--nSize;
+
+				for(; i < nSize; ++i)
+					pList[i] = pList[i + 1];
+
+				return Error_Success;
+			}
+		}
+
+		return Error_Fail;
+	}
+
+	/*
 	 * Clear
 	 */
 	void Clear()
@@ -90,9 +111,9 @@
 	}
 
 	/*
-	 * GetSize
+	 * Size
 	 */
-	uint32 GetSize() const
+	uint32 Size() const
 	{
 		return nSize;
 	}
--- a/LightClone/Source/CodePanel.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/CodePanel.cpp	Thu Sep 15 12:13:40 2011 -0700
@@ -17,7 +17,7 @@
  */
 ErrorCode CodePanel::Initialize(ResourceManager* pResourceManager)
 {
-	ErrorCode eCode = GuiContainer::Initialize(pResourceManager);
+	ErrorCode eCode = GuiElement::Initialize(pResourceManager);
 	if(eCode == Error_Success)
 	{
 		for(uint32 i = 0; i < 4; ++i)
--- a/LightClone/Source/CodePanel.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/CodePanel.h	Thu Sep 15 12:13:40 2011 -0700
@@ -6,13 +6,18 @@
 #define __CODEPANEL_H__
 
 #include "Core.h"
-#include "GuiContainer.h"
+#include "GuiImage.h"
 
 /*
  * CodePanel
  */
-class CodePanel : public GuiContainer
+class CodePanel : public GuiElement
 {
+	/*
+	 * pSlot
+	 */
+	GuiImage** pSlot;
+
 public:
 
 	/*
--- a/LightClone/Source/EventSystem.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/EventSystem.cpp	Thu Sep 15 12:13:40 2011 -0700
@@ -48,7 +48,7 @@
  */
 void EventSystem::Post(const Event& kEvent)
 {
-	for(uint32 i = 0; i < kSinks.GetSize(); ++i)
+	for(uint32 i = 0; i < kSinks.Size(); ++i)
 	{
 		if(kSinks[i]->ProcessEvent(kEvent) == EventResult_Stop)
 		{
@@ -62,7 +62,7 @@
  */
 void EventSystem::Update(float fElapsed)
 {
-	for(uint32 i = 0; i < kSources.GetSize(); ++i)
+	for(uint32 i = 0; i < kSources.Size(); ++i)
 	{
 		kSources[i]->Update(this, fElapsed);
 	}
--- a/LightClone/Source/GuiContainer.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * GuiContainer
- */
-
-#include "GuiContainer.h"
-
-/*
- * GuiContainer
- */
-GuiContainer::GuiContainer()
-{
-}
-
-/*
- * ~GuiContainer
- */
-GuiContainer::~GuiContainer()
-{
-	for(uint32 i = 0; i < kChildren.GetSize(); ++i)
-	{
-		delete kChildren[i];
-	}
-
-	kChildren.Clear();
-}
-
-/*
- * Initialize
- */
-ErrorCode GuiContainer::Initialize(ResourceManager* pResourceManager)
-{
-	ErrorCode eCode = Error_Success;
-
-	for(uint32 i = 0; i < kChildren.GetSize() && eCode == Error_Success; ++i)
-	{
-		eCode = kChildren[i]->Initialize(pResourceManager);
-	}
-
-	return eCode;
-}
-
-/*
- * Terminate
- */
-void GuiContainer::Terminate()
-{
-	for(uint32 i = 0; i < kChildren.GetSize(); ++i)
-	{
-		kChildren[i]->Terminate();
-	}
-}
-
-/*
- * Update
- */
-void GuiContainer::Update(float fElapsed)
-{
-	for(uint32 i = 0; i < kChildren.GetSize(); ++i)
-	{
-		kChildren[i]->Update(fElapsed);
-	}
-
-	Layout(kChildren);
-}
-
-/*
- * Render
- */
-void GuiContainer::Render(RenderContext& kContext, Camera& kCamera)
-{
-	for(uint32 i = 0; i < kChildren.GetSize(); ++i)
-	{
-		kChildren[i]->Render(kContext, kCamera);
-	}
-}
-
-/*
- * Pick
- */
-GuiElement* GuiContainer::Pick(float fX, float fY)
-{
-	GuiElement* pElement = NULL;
-
-	for(uint32 i = 0; i < kChildren.GetSize() && !pElement; ++i)
-	{
-		pElement = kChildren[i]->Pick(fX, fY);
-	}
-
-	return pElement;
-}
-
-/*
- * Add
- */
-ErrorCode GuiContainer::Add(GuiElement* pElement)
-{
-	return kChildren.Add(pElement);
-}
-
-/*
- * Layout
- */
-void GuiContainer::Layout(GuiElementList& kElements)
-{
-}
\ No newline at end of file
--- a/LightClone/Source/GuiContainer.h	Wed Sep 14 17:24:49 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * GuiContainer
- */
-
-#ifndef __GUICONTAINER_H__
-#define __GUICONTAINER_H__
-
-#include "Core.h"
-#include "GuiElement.h"
-
-/*
- * GuiContainer
- */
-class GuiContainer : public GuiElement
-{
-	/*
-	 * pChildren
-	 */
-	GuiElementList kChildren;
-
-public:
-
-	/*
-	 * GuiContainer
-	 */
-	GuiContainer();
-
-	/*
-	 * ~GuiContainer
-	 */
-	~GuiContainer();
-
-	/*
-	 * Initialize
-	 */
-	virtual ErrorCode Initialize(ResourceManager* pResourceManager);
-
-	/*
-	 * Terminate
-	 */
-	virtual void Terminate();
-
-	/*
-	 * Update
-	 */
-	virtual void Update(float fElapsed);
-
-	/*
-	 * Render
-	 */
-	virtual void Render(RenderContext& kContext, Camera& kCamera);
-
-	/*
-	 * Pick
-	 */
-	virtual GuiElement* Pick(float fX, float fY);
-
-	/*
-	 * Add
-	 */
-	ErrorCode Add(GuiElement* pElement);
-
-protected:
-
-	/*
-	 * Layout
-	 */
-	virtual void Layout(GuiElementList& kElements);
-};
-
-#endif //__GUICONTAINER_H__
--- a/LightClone/Source/GuiElement.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/GuiElement.cpp	Thu Sep 15 12:13:40 2011 -0700
@@ -19,6 +19,43 @@
 }
 
 /*
+ * Initialize
+ */
+ErrorCode GuiElement::Initialize(ResourceManager* pResourceManager)
+{
+	return Error_Success;
+}
+
+/*
+ * Terminate
+ */
+void GuiElement::Terminate()
+{
+}
+
+/*
+ * Update
+ */
+void GuiElement::Update(float fElapsed)
+{
+	for(uint32 i = 0; i < kChildren.Size(); ++i)
+	{
+		kChildren[i]->Update(fElapsed);
+	}
+}
+
+/*
+ * Render
+ */
+void GuiElement::Render(RenderContext& kContext, Camera& kCamera)
+{
+	for(uint32 i = 0; i < kChildren.Size(); ++i)
+	{
+		kChildren[i]->Render(kContext, kCamera);
+	}
+}
+
+/*
  * Attach
  */
 void GuiElement::Attach(GuiElement* pInstance)
@@ -103,3 +140,85 @@
 
 	return Rectangle2(kLocation.y, kLocation.y, kDimensions.x, kDimensions.y).Contains(fX, fY) ? this : NULL;
 }
+
+/*
+ * Add
+ */
+ErrorCode GuiElement::Add(GuiElement* pElement)
+{
+	ErrorCode eCode = Error_Fail;
+	
+	if(pElement)
+	{
+		eCode = kChildren.Add(pElement);
+		if(eCode == Error_Success)
+		{
+			pElement->Attach(this);	
+		}
+	}
+
+	return eCode;
+}
+
+/*
+ * Remove
+ */
+ErrorCode GuiElement::Remove(GuiElement* pElement)
+{
+	ErrorCode eCode = Error_Fail;
+
+	if(pElement)
+	{
+		eCode = kChildren.Remove(pElement);
+		if(eCode == Error_Success)
+		{
+			pElement->Detach();
+		}
+	}
+
+	return eCode;
+}
+
+/*
+ * AllowDrag
+ */
+bool GuiElement::AllowDrag() const
+{
+	return false;
+}
+
+/*
+ * AllowDrop
+ */
+bool GuiElement::AllowDrop() const
+{
+	return false;
+}
+
+/*
+ * OnMouseDown
+ */
+void GuiElement::OnMouseDown(uint32 nButton, float fX, float fY)
+{
+}
+
+/*
+ * OnMouseUp
+ */
+void GuiElement::OnMouseUp(uint32 nButton, float fX, float fY)
+{
+}
+
+/*
+ * OnDrag
+ */
+void GuiElement::OnDrag(float fX, float fY)
+{
+}
+
+/*
+ * OnDrop
+ */
+void GuiElement::OnDrop(GuiElement* pSource, float fX, float fY)
+{
+}
--- a/LightClone/Source/GuiElement.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/GuiElement.h	Thu Sep 15 12:13:40 2011 -0700
@@ -16,6 +16,13 @@
  */
 class GuiElement
 {
+public:
+
+	/*
+	 * List
+	 */
+	typedef ArrayList<GuiElement*> List;
+
 protected:
 
 	/*
@@ -33,6 +40,16 @@
 	 */
 	D3DXVECTOR2 kDimensions;
 
+	/*
+	 * kColor
+	 */
+	D3DCOLOR kColor;
+
+	/*
+	 * kChildren
+	 */
+	List kChildren;
+
 public:
 
 	/*
@@ -48,22 +65,22 @@
 	/*
 	 * Initialize
 	 */
-	virtual ErrorCode Initialize(ResourceManager* pResourceManager) = 0;
+	virtual ErrorCode Initialize(ResourceManager* pResourceManager);
 
 	/*
 	 * Terminate
 	 */
-	virtual void Terminate() = 0;
+	virtual void Terminate();
 
 	/*
 	 * Update
 	 */
-	virtual void Update(float fElapsed) = 0;
+	virtual void Update(float fElapsed);
 
 	/*
 	 * Render
 	 */
-	virtual void Render(RenderContext& kContext, Camera& kCamera) = 0;
+	virtual void Render(RenderContext& kContext, Camera& kCamera);
 
 	/*
 	 * Attach
@@ -114,11 +131,46 @@
 	 * Pick
 	 */
 	virtual GuiElement* Pick(float fX, float fY);
+
+	/*
+	 * Add
+	 */
+	ErrorCode Add(GuiElement* pElement);
+
+	/*
+	 * Remove
+	 */
+	ErrorCode Remove(GuiElement* pElement);
+
+	/*
+	 * AllowDrag
+	 */
+	virtual bool AllowDrag() const;
+
+	/*
+	 * AllowDrop
+	 */
+	virtual bool AllowDrop() const;
+
+	/*
+	 * OnMouseDown
+	 */
+	virtual void OnMouseDown(uint32 nButton, float fX, float fY);
+
+	/*
+	 * OnMouseUp
+	 */
+	virtual void OnMouseUp(uint32 nButton, float fX, float fY);
+
+	/*
+	 * OnDrag
+	 */
+	virtual void OnDrag(float fX, float fY);
+
+	/*
+	 * OnDrop
+	 */
+	virtual void OnDrop(GuiElement* pSource, float fX, float fY);
 };
 
-/*
- * GuiElementList
- */
-typedef ArrayList<GuiElement*> GuiElementList;
-
 #endif //__GUIELEMENT_H__
--- a/LightClone/Source/GuiInterface.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/GuiInterface.cpp	Thu Sep 15 12:13:40 2011 -0700
@@ -7,26 +7,23 @@
 /*
  * GuiInterface
  */
-GuiInterface::GuiInterface()
+GuiInterface::GuiInterface() : pInputManager(NULL), pDragSource(NULL)
 {
-	pRoot = new GuiContainer();
-}
-
-/*
- * ~GuiInterface
- */
-GuiInterface::~GuiInterface()
-{
-	delete pRoot;
-	pRoot = NULL;
 }
 
 /*
  * Initialize
  */
-ErrorCode GuiInterface::Initialize(ResourceManager* pResourceManager)
+ErrorCode GuiInterface::Initialize(ResourceManager* pResourceManager, InputManager* pInput)
 {
-	return pRoot->Initialize(pResourceManager);
+	ErrorCode eCode = GuiElement::Initialize(pResourceManager);
+	if(eCode == Error_Success)
+	{
+		pInputManager = pInput;
+		//ASSERT(pInputManager);
+	}
+
+	return eCode;
 }
 
 /*
@@ -34,7 +31,7 @@
  */
 void GuiInterface::Terminate()
 {
-	pRoot->Terminate();
+	GuiElement::Terminate();
 }
 
 /*
@@ -42,34 +39,48 @@
  */
 void GuiInterface::Update(float fElapsed)
 {
-	pRoot->Update(fElapsed);
-}
+	const float fX = pInputManager->GetMouseX();
+	const float fY = pInputManager->GetMouseY();
+
+	GuiElement::Update(fElapsed);
 
-/*
- * Render
- */
-void GuiInterface::Render(RenderContext& kContext, Camera& kCamera)
-{
-	//TODO: Should I send the camera down the tree?  Ideally I would have a
-	//		single VB for all UI quads, so really the interface could setup
-	//		the camera and effect at this point.  May also need a wrapper
-	//		around render context (GuiRenderContext)
+	if(pInputManager->IsButtonDown(MouseButton_Left) && !pInputManager->WasButtonDown(MouseButton_Left))
+	{
+		GuiElement* pElement = Pick(fX, fY);
+		if(pElement)
+		{
+			pElement->OnMouseDown(MouseButton_Left, fX, fY);
 
-	pRoot->Render(kContext, kCamera);
-}
+			//TODO: pElement could also be the source of a drag operation
+		}
+	}
+	else
 
-/*
- * Pick
- */
-GuiElement* GuiInterface::Pick(float fX, float fY)
-{
-	return pRoot->Pick(fX, fY);
-}
+	if(!pInputManager->IsButtonDown(MouseButton_Left) && pInputManager->WasButtonDown(MouseButton_Left))
+	{
+		GuiElement* pElement = Pick(fX, fY);
+		if(pElement)
+		{
+			GuiElement* pContainer = pElement;
+
+			if(pDragSource)
+			{
+				while(pContainer && !pElement->AllowDrop())
+				{
+					pContainer = pContainer->GetContainer();
+				}
 
-/*
- * GetRoot
- */
-GuiContainer* GuiInterface::GetRoot()
-{
-	return pRoot;
+				if(pContainer)
+				{
+					pContainer->OnDrop(pDragSource, fX, fY);
+				}
+			}
+			else
+			{
+				pElement->OnMouseUp(MouseButton_Left, fX, fY);
+			}
+
+			pDragSource = NULL;
+		}
+	}
 }
--- a/LightClone/Source/GuiInterface.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/GuiInterface.h	Thu Sep 15 12:13:40 2011 -0700
@@ -6,17 +6,23 @@
 #define __GUIINTERFACE_H__
 
 #include "Core.h"
-#include "GuiContainer.h"
+#include "GuiElement.h"
+#include "InputManager.h"
 
 /*
  * GuiInterface
  */
-class GuiInterface
+class GuiInterface : public GuiElement
 {
 	/*
-	 * pRoot
+	 * pInputManager
 	 */
-	GuiContainer* pRoot;
+	InputManager* pInputManager;
+
+	/*
+	 * pDragSource
+	 */
+	GuiElement* pDragSource;
 
 public:
 
@@ -26,14 +32,9 @@
 	GuiInterface();
 
 	/*
-	 * ~GuiInterface
-	 */
-	~GuiInterface();
-
-	/*
 	 * Initialize
 	 */
-	ErrorCode Initialize(ResourceManager* pResourceManager);
+	ErrorCode Initialize(ResourceManager* pResourceManager, InputManager* pInputManager);
 
 	/*
 	 * Terminate
@@ -45,20 +46,9 @@
 	 */
 	void Update(float fElapsed);
 
-	/*
-	 * Render
-	 */
-	void Render(RenderContext& kContext, Camera& kCamera);
+private:
 
-	/*
-	 * Pick
-	 */
-	GuiElement* Pick(float fX, float fY);
-
-	/*
-	 * GetRoot
-	 */
-	GuiContainer* GetRoot();
+	using GuiElement::Initialize;
 };
 
 #endif //__GUIINTERFACE_H__
--- a/LightClone/Source/InputManager.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/InputManager.h	Thu Sep 15 12:13:40 2011 -0700
@@ -28,6 +28,16 @@
 };
 
 /*
+ * MouseButton
+ */
+enum
+{
+	MouseButton_Left,
+	MouseButton_Right,
+	MouseButton_Middle,
+};
+
+/*
  * InputEvent
  */
 struct InputEvent : public Event
--- a/LightClone/Source/Interface.h	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/Interface.h	Thu Sep 15 12:13:40 2011 -0700
@@ -8,7 +8,6 @@
 #include "Core.h"
 #include "RenderContext.h"
 #include "ResourceManager.h"
-#include "GuiContainer.h"
 #include "EventSystem.h"
 #include "InputManager.h"
 
--- a/LightClone/Source/World.cpp	Wed Sep 14 17:24:49 2011 -0700
+++ b/LightClone/Source/World.cpp	Thu Sep 15 12:13:40 2011 -0700
@@ -260,6 +260,7 @@
 
 	kContext.Begin(nColor);
 
+	//TODO: Remove
 	if(nGameState >= GameState_Active)
 	{
 		kCameraController.SetMode(CameraMode_3D);
@@ -277,9 +278,6 @@
  */
 ErrorCode World::InitializeInterface(ResourceManager* pResourceManager)
 {
-	GuiContainer* pRoot = kInterface.GetRoot();
-	//ASSERT(pRoot != NULL);
-
 	GuiLabel*
 	pLabel = new GuiLabel();
 	pLabel->Initialize(pResourceManager);
@@ -288,15 +286,10 @@
 	pLabel->SetFlags(GuiLabelFlag_CenterX | GuiLabelFlag_CenterY);
 	pLabel->SetPosition(0.5f * ScreenSizeX, 0.5f * ScreenSizeY);
 
-	pRoot->Add(pLabel);
-
-	//return kInterface.Initialize(pResourceManager);
-
 	/*
-	GuiElement* pRoot = kInterface.GetRoot();
-
 	//CodePanel* 
 	pToolbar = new CodePanel(8);
+	pToolbar->Initialize(pResourceManager);
 	pToolbar->SetBackgroundTexture("Data\\Textures\\CodePanel.tga");
 	pToolbar->SetSlotTexture("Data\\Textures\\Slot.tga");
 
@@ -304,47 +297,43 @@
 	pMain = new CodePanel(16);
 	pMain->SetBackgroundTexture("Data\\Textures\\CodePanel.tga");
 	pMain->SetSlotTexture("Data\\Textures\\Slot.tga");
+	pMain->Subscribe(CodePanel::Drop, &World::OnDrop, this);
 
 	//CodePanel* 
 	pFunctionA = new CodePanel(16);
 	pFunctionA->SetBackgroundTexture("Data\\Textures\\CodePanel.tga");
 	pFunctionA->SetSlotTexture("Data\\Textures\\Slot.tga");
+	pFunctionA->Subscribe(CodePanel::Drop, &World::OnDrop, this);
 
 	//CodePanel* 
 	pFunctionB = new CodePanel(16);
 	pFunctionB->SetBackgroundTexture("Data\\Textures\\CodePanel.tga");
 	pFunctionB->SetSlotTexture("Data\\Textures\\Slot.tga");
-
-	//SelectorPanel*
-	pSelectorPanel = new SelectorPanel();
-	pSelectorPanel->SetLeftTexture("Data\\Textures\\Left.tga");
-	pSelectorPanel->SetRightTexture("Data\\Textures\\Right.tga");
-	pSelectorPanel->Add(pFunctionA);
-	pSelectorPanel->Add(pFunctionB);
+	pFunctionB->Subscribe(CodePanel::Drop, &World::OnDrop, this);
 
 	//GuiButton*
 	pButtonStart = new GuiButton();
 	pButtonStart->SetTexture("Data\\Textures\\Play.tga");
 	pButtonStart->SetDimensions(...);
-	pButtonStart->SetCallback(&World::OnClick, this);
+	pButtonStart->Subscribe(GuiButton::Click, &World::OnClick, this);
 
 	//GuiButton*
 	pButtonStop = new GuiButton();
 	pButtonStop->SetTexture("Data\\Textures\\Stop.tga");
 	pButtonStop->SetDimensions(...);
-	pButtonStop->SetCallback(&World::OnClick, this);
+	pButtonStart->Subscribe(GuiButton::Click, &World::OnClick, this);
 
 	//GuiButton*
 	pButtonReset = new GuiButton();
 	pButtonReset->SetTexture("Data\\Textures\\Reset.tga");
 	pButtonReset->SetDimensions(...);
-	pButtonReset->SetCallback(&World::OnClick, this);
+	pButtonStart->Subscribe(GuiButton::Click, &World::OnClick, this);
 
 	//GuiButton*
 	pButtonExit = new GuiButton();
 	pButtonExit->SetTexture("Data\\Textures\\Exit.tga");
 	pButtonExit->SetDimensions(...);
-	pButtonExit->SetCallback(&World::OnClick, this);
+	pButtonStart->Subscribe(GuiButton::Click, &World::OnClick, this);
 
 	//GuiPanel*
 	pControlPanel = new GuiPanel();
@@ -385,6 +374,8 @@
 	pRoot->Add(pConfirmDialog);
 	*/
 
+	kInterface.Add(pLabel);
+
 	return Error_Success;
 }