view LightClone/Source/GuiButton.cpp @ 23:a785b0aaf004

More work on the Gui system
author koryspansel
date Thu, 15 Sep 2011 21:45:00 -0700
parents b4dc5d674e22
children 3a63df04f3c0
line wrap: on
line source

/*
 * GuiButton
 */

#include "GuiButton.h"
#include "VertexTypes.h"

/*
 * EventClick
 */
const char* GuiButton::EventClick = "GuiButton:Click";

/*
 * GuiButton
 */
GuiButton::GuiButton() : nState(GuiButtonState_Normal), pEffect(NULL), pVertexBuffer(NULL), pFont(NULL)
{
	memset(pTexture, 0, sizeof(pTexture));
}

/*
 * Initialize
 */
ErrorCode GuiButton::Initialize(ResourceManager* pManager)
{
	ErrorCode eCode = pManager->CreateEffectFromFile("Data\\Shaders\\TexturedQuad.fx", &pEffect);
	if(eCode == Error_Success)
	{
		eCode = pManager->CreateVertexBuffer(6 * sizeof(Vertex::Quad), D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED, &pVertexBuffer);
		if(eCode == Error_Success)
		{
			eCode = SetupVertexBuffer();
			if(eCode == Error_Success)
			{
				pResourceManager = pManager;
			}
		}
	}

	return eCode;
}

/*
 * Terminate
 */
void GuiButton::Terminate()
{
	if(pFont)
	{
		pFont->Release();
		pFont = NULL;
	}

	for(uint32 i = 0; i < GuiButtonState_Count; ++i)
	{
		if(pTexture[i])
		{
			pTexture[i]->Release();
			pTexture[i] = NULL;
		}
	}

	if(pVertexBuffer)
	{
		pVertexBuffer->Release();
		pVertexBuffer = NULL;
	}

	if(pEffect)
	{
		pEffect->Release();
		pEffect = NULL;
	}
}

/*
 * Update
 */
void GuiButton::Update(float fElapsed)
{
}

/*
 * Render
 */
void GuiButton::Render(RenderContext& kContext, Camera& kCamera)
{
	if(bVisible)
	{
		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);

			kContext.ApplyCameraToEffect(kCamera, pEffect);

			D3DXMATRIX kScale;
			D3DXMatrixScaling(&kScale, kDimensions.x, kDimensions.y, 1.0f);

			const D3DXVECTOR2& kLocation = GetPosition();

			D3DXMATRIX kTranslate;
			D3DXMatrixTranslation(&kTranslate, fOffsetX + kLocation.x + 0.5f, fOffsetY - kLocation.y + 0.5f, 0.0f);

			D3DXMATRIX kWorldMatrix;
			D3DXMatrixMultiply(&kWorldMatrix, &kScale, &kTranslate);

			pEffect->SetMatrix(pEffect->GetParameterByName(NULL, "kWorld"), &kWorldMatrix);
			pEffect->SetVector(pEffect->GetParameterByName(NULL, "kColor"), &kColorVector);
			pEffect->SetTexture(pEffect->GetParameterByName(NULL, "kTexture"), pTexture[nState]);

			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();

			if(pFont && kText.Length() > 0)
			{
				const int32 nX		= (int32)(kLocation.x + 0.5f * kDimensions.x);
				const int32 nY		= (int32)(kLocation.y + 0.5f * kDimensions.y);

				RECT kRectangle;
				kRectangle.left		= nX;
				kRectangle.top		= nY;
				kRectangle.right	= nX;
				kRectangle.bottom	= nY;

				const uint32 nLength = kText.Length();

				pFont->DrawTextA(NULL, kText, nLength, &kRectangle, DT_CENTER | DT_VCENTER | DT_CALCRECT, kColor);
				pFont->DrawTextA(NULL, kText, nLength, &kRectangle, DT_CENTER | DT_VCENTER, kColor);
			}
		}

		GuiElement::Render(kContext, kCamera);
	}
}


/*
 * 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;
}

/*
 * SetFont
 */
ErrorCode GuiButton::SetFont(const char* pName, uint32 nSize, uint32 nWeight)
{
	if(pFont)
	{
		pFont->Release();
		pFont = NULL;
	}

	return pResourceManager->CreateFontFromName(pName, nSize, nWeight, &pFont);
}

/*
 * SetText
 */
void GuiButton::SetText(const char* pText)
{
	kText = pText;
}

/*
 * OnMouseDown
 */
void GuiButton::OnMouseDown(uint32 nButton, float fX, float fY)
{
	//TODO: Proper states and click handling
	GuiEventArguments kArguments;
	kArguments.pSource = this;

	Fire(EventClick, kArguments);
}

/*
 * OnMouseUp
 */
void GuiButton::OnMouseUp(uint32 nButton, float fX, float fY)
{
}

/*
 * SetupVertexBuffer
 */
ErrorCode GuiButton::SetupVertexBuffer()
{
	Vertex::Quad* pVertices = NULL;

	HRESULT hResult = pVertexBuffer->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
	if(FAILED(hResult))
	{
		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);

	pVertexBuffer->Unlock();

	return Error_Success;
}