/*
** Haaf's Game Engine 1.7
** Copyright (C) 2003-2007, Relish Games
** hge.relishgames.com
**
** hgeGUI default controls implementation
*/
#include "hgeguictrls.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*
** hgeGUIText
*/
hgeGUIText::hgeGUIText(int _id, float x, float y, float w, float h, hgeFont *fnt)
{
id=_id;
bStatic=true;
bVisible=true;
bEnabled=true;
rect.Set(x, y, x+w, y+h);
font=fnt;
tx=x;
ty=y+(h-fnt->GetHeight())/2.0f;
text[0]=0;
}
void hgeGUIText::SetMode(int _align)
{
align=_align;
if(align==HGETEXT_RIGHT) tx=rect.x2;
else if(align==HGETEXT_CENTER) tx=(rect.x1+rect.x2)/2.0f;
else tx=rect.x1;
}
void hgeGUIText::SetText(const char *_text)
{
strncpy(text, _text, sizeof(text)-1);
text[sizeof(text) - 1] = '\0';
}
void hgeGUIText::printf(const char *format, ...)
{
va_list vl;
va_start(vl, format);
vsnprintf(text, sizeof(text)-1, format, vl);
va_end(vl);
}
void hgeGUIText::Render()
{
font->SetColor(color);
font->Render(tx,ty,align,text);
}
/*
** hgeGUIButton
*/
hgeGUIButton::hgeGUIButton(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty)
{
id=_id;
bStatic=false;
bVisible=true;
bEnabled=true;
rect.Set(x, y, x+w, y+h);
bPressed=false;
bTrigger=false;
sprUp = new hgeSprite(tex, tx, ty, w, h);
sprDown = new hgeSprite(tex, tx+w, ty, w, h);
}
hgeGUIButton::~hgeGUIButton()
{
if(sprUp) delete sprUp;
if(sprDown) delete sprDown;
}
void hgeGUIButton::Render()
{
if(bPressed) sprDown->Render(rect.x1, rect.y1);
else sprUp->Render(rect.x1, rect.y1);
}
bool hgeGUIButton::MouseLButton(bool bDown)
{
if(bDown)
{
bOldState=bPressed; bPressed=true;
return false;
}
else
{
if(bTrigger) bPressed=!bOldState;
else bPressed=false;
return true;
}
}
/*
** hgeGUISlider
*/
hgeGUISlider::hgeGUISlider(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty, float sw, float sh, bool vertical)
{
id=_id;
bStatic=false;
bVisible=true;
bEnabled=true;
bPressed=false;
bVertical=vertical;
rect.Set(x, y, x+w, y+h);
mode=HGESLIDER_BAR;
fMin=0; fMax=100; fVal=50;
sl_w=sw; sl_h=sh;
sprSlider=new hgeSprite(tex, tx, ty, sw, sh);
}
hgeGUISlider::~hgeGUISlider()
{
if(sprSlider) delete sprSlider;
}
void hgeGUISlider::SetValue(float _fVal)
{
if(_fVal<fMin) fVal=fMin;
else if(_fVal>fMax) fVal=fMax;
else fVal=_fVal;
}
void hgeGUISlider::Render()
{
float xx, yy;
float x1,y1,x2,y2;
xx=rect.x1+(rect.x2-rect.x1)*(fVal-fMin)/(fMax-fMin);
yy=rect.y1+(rect.y2-rect.y1)*(fVal-fMin)/(fMax-fMin);
if(bVertical)
switch(mode)
{
case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=rect.x2; y2=yy; break;
case HGESLIDER_BARRELATIVE: x1=rect.x1; y1=(rect.y1+rect.y2)/2; x2=rect.x2; y2=yy; break;
case HGESLIDER_SLIDER: x1=(rect.x1+rect.x2-sl_w)/2; y1=yy-sl_h/2; x2=(rect.x1+rect.x2+sl_w)/2; y2=yy+sl_h/2; break;
}
else
switch(mode)
{
case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=xx; y2=rect.y2; break;
case HGESLIDER_BARRELATIVE: x1=(rect.x1+rect.x2)/2; y1=rect.y1; x2=xx; y2=rect.y2; break;
case HGESLIDER_SLIDER: x1=xx-sl_w/2; y1=(rect.y1+rect.y2-sl_h)/2; x2=xx+sl_w/2; y2=(rect.y1+rect.y2+sl_h)/2; break;
}
sprSlider->RenderStretch(x1, y1, x2, y2);
}
bool hgeGUISlider::MouseLButton(bool bDown)
{
bPressed=bDown;
return false;
}
bool hgeGUISlider::MouseMove(float x, float y)
{
if(bPressed)
{
if(bVertical)
{
if(y>rect.y2-rect.y1) y=rect.y2-rect.y1;
if(y<0) y=0;
fVal=fMin+(fMax-fMin)*y/(rect.y2-rect.y1);
}
else
{
if(x>rect.x2-rect.x1) x=rect.x2-rect.x1;
if(x<0) x=0;
fVal=fMin+(fMax-fMin)*x/(rect.x2-rect.x1);
}
return true;
}
return false;
}
/*
** hgeGUIListbox
*/
hgeGUIListbox::hgeGUIListbox(int _id, float x, float y, float w, float h, hgeFont *fnt, DWORD tColor, DWORD thColor, DWORD hColor)
{
id=_id;
bStatic=false;
bVisible=true;
bEnabled=true;
rect.Set(x, y, x+w, y+h);
font=fnt;
sprHighlight=new hgeSprite(0, 0, 0, w, fnt->GetHeight());
sprHighlight->SetColor(hColor);
textColor=tColor;
texthilColor=thColor;
pItems=0;
nItems=0;
nSelectedItem=0;
nTopItem=0;
mx=0; my=0;
}
hgeGUIListbox::~hgeGUIListbox()
{
Clear();
if(sprHighlight) delete sprHighlight;
}
int hgeGUIListbox::AddItem(char *item)
{
hgeGUIListboxItem *pItem=pItems, *pPrev=0, *pNew;
pNew = new hgeGUIListboxItem;
memcpy(pNew->text, item, min(sizeof(pNew->text), strlen(item)+1));
pNew->text[sizeof(pNew->text)-1]='\0';
pNew->next=0;
while(pItem) { pPrev=pItem; pItem=pItem->next; }
if(pPrev) pPrev->next=pNew;
else pItems=pNew;
nItems++;
return nItems-1;
}
void hgeGUIListbox::DeleteItem(int n)
{
int i;
hgeGUIListboxItem *pItem=pItems, *pPrev=0;
if(n<0 || n>=GetNumItems()) return;
for(i=0;i<n;i++) { pPrev=pItem; pItem=pItem->next; }
if(pPrev) pPrev->next=pItem->next;
else pItems=pItem->next;
delete pItem;
nItems--;
}
char *hgeGUIListbox::GetItemText(int n)
{
int i;
hgeGUIListboxItem *pItem=pItems;
if(n<0 || n>=GetNumItems()) return 0;
for(i=0;i<n;i++) pItem=pItem->next;
return pItem->text;
}
void hgeGUIListbox::Clear()
{
hgeGUIListboxItem *pItem=pItems, *pNext;
while(pItem)
{
pNext=pItem->next;
delete pItem;
pItem=pNext;
}
pItems=0;
nItems=0;
}
void hgeGUIListbox::Render()
{
int i;
hgeGUIListboxItem *pItem=pItems;
for(i=0;i<nTopItem;i++) pItem=pItem->next;
for(i=0;i<GetNumRows();i++)
{
if(i>=nItems) return;
if(nTopItem+i == nSelectedItem)
{
sprHighlight->Render(rect.x1,rect.y1+i*font->GetHeight());
font->SetColor(texthilColor);
}
else
font->SetColor(textColor);
font->Render(rect.x1+3, rect.y1+i*font->GetHeight(), HGETEXT_LEFT, pItem->text);
pItem=pItem->next;
}
}
bool hgeGUIListbox::MouseLButton(bool bDown)
{
int nItem;
if(bDown)
{
nItem=nTopItem+int(my)/int(font->GetHeight());
if(nItem<nItems)
{
nSelectedItem=nItem;
return true;
}
}
return false;
}
bool hgeGUIListbox::MouseWheel(int nNotches)
{
nTopItem-=nNotches;
if(nTopItem<0) nTopItem=0;
if(nTopItem>GetNumItems()-GetNumRows()) nTopItem=GetNumItems()-GetNumRows();
return true;
}
bool hgeGUIListbox::KeyClick(int key, int chr)
{
switch(key)
{
case HGEK_DOWN:
if(nSelectedItem < nItems-1)
{
nSelectedItem++;
if(nSelectedItem > nTopItem+GetNumRows()-1) nTopItem=nSelectedItem-GetNumRows()+1;
return true;
}
break;
case HGEK_UP:
if(nSelectedItem > 0)
{
nSelectedItem--;
if(nSelectedItem < nTopItem) nTopItem=nSelectedItem;
return true;
}
break;
}
return false;
}