If you have comments or questions concerning this source file, discuss them in the forum.
/*
Copyright (c) 2002 Nicolai Haehnle
See the license.txt for details. If that file was not included in the
source distributions, please email <prefect@rtts.org>
*/
// gui_label.cpp -- GLabel implementation
#include "library.h"
#include "hal.h"
#include "gui_label.h"
/*
==============
GLabel::GLabel
Initialize everything
==============
*/
GLabel::GLabel(GPanel *pParent, int x, int y, int w, int h, const char *szText, int iAlign)
: GPanel(pParent, x, y, w, h)
{
m_pszText = 0;
m_pFont = 0;
m_pPic = 0,
m_pSprite = 0;
m_iAlign = iAlign;
m_iYSpacing = 0;
m_iBorderX = m_iBorderY = 0;
m_iScrollX = m_iScrollY = 0;
if (szText)
SetText(szText);
}
GLabel::GLabel(GPanel *pParent, const char *szPic, int type, u32 colorkey,
int x, int y, int w, int h)
: GPanel(pParent, x, y, w, h)
{
m_pszText = 0;
m_pFont = 0;
m_pPic = 0;
m_pSprite = 0;
m_iAlign = 0;
m_iYSpacing = 0;
m_iBorderX = m_iBorderY = 0;
m_iScrollX = m_iScrollY = 0;
if (szPic)
SetPicture(szPic, type, colorkey);
}
/*
==============
GLabel::~GLabel
Free allocated resources
==============
*/
GLabel::~GLabel()
{
Clear();
}
/*
==============
GLabel::Clear
Clears text or picture or sprite
==============
*/
void GLabel::Clear()
{
if (m_pPic) {
m_pPic->Release();
m_pPic = 0;
}
if (m_pszText) {
L_Free(m_pszText);
m_pszText = 0;
}
if (m_pSprite) {
SPR_Free(m_pSprite);
m_pSprite = 0;
}
if (m_pFont) {
m_pFont->Release();
m_pFont = 0;
}
}
/*
==============
GLabel::SetText
Replace the label's text with a new one. pszText can be 0
==============
*/
void GLabel::SetText(const char *pszText)
{
Clear();
if (pszText) {
m_pszText = L_Strdup(pszText, TAG_GUI);
if (!m_pFont)
m_pFont = HFont::Get("font");
}
}
/*
==============
GLabel::SetPicture
Replace the current picture with a new one.
Ownership is not transferred in the direct version.
==============
*/
void GLabel::SetPicture(const char *szPic, int type, u32 colorkey)
{
Clear();
if (szPic)
m_pPic = HPicture::Get(szPic, type, colorkey);
}
void GLabel::SetPicture(HPicture *pPic)
{
Clear();
if (pPic) {
m_pPic = pPic;
pPic->AddRef();
}
}
/*
==============
GLabel::SetSprite
Makes the label display the given sprite.
Ownership is not transferred in the direct version
==============
*/
void GLabel::SetSprite(const char *szSprite)
{
Clear();
if (szSprite)
m_pSprite = SPR_Get(szSprite);
}
void GLabel::SetSprite(sprite_t *sprite)
{
Clear();
if (sprite) {
m_pSprite = sprite;
m_pSprite->used++;
}
}
/*
==============
GLabel::SetAlign
Change the label's alignment
==============
*/
void GLabel::SetAlign(int iAlign)
{
m_iAlign = iAlign;
}
/*
==============
GLabel::SetBorder
Designates a border which is kept free of text.
==============
*/
void GLabel::SetBorder(int x, int y)
{
m_iBorderX = x;
m_iBorderY = y;
}
/*
==============
GLabel::AdjustSize
Adjust the size to fit the text exactly without moving the
point of alignment
==============
*/
void GLabel::AdjustSize()
{
int iw, ih;
int w, h;
if (m_pszText) {
m_pFont->StringSize(m_pszText, (m_iAlign & align_wrap) ? m_rc.size[0] : -1,
m_iYSpacing, &w, &h);
} else if (m_pPic) {
w = m_pPic->size[0];
h = m_pPic->size[1];
} else
return; // adjustsize for sprites? problematic with animations
GetIconSize(&iw, &ih);
if (iw)
w += iw + 8; // 8 pxls of additional spacing
if (ih > h)
h = ih;
w += m_iBorderX*2;
h += m_iBorderY*2;
switch(m_iAlign & halign_mask) {
case halign_center:
m_rc.pos[0] += (m_rc.size[0] - w) / 2;
break;
case halign_right:
m_rc.pos[0] += m_rc.size[0] - w;
break;
}
m_rc.size[0] = w;
switch(m_iAlign & valign_mask) {
case valign_center:
m_rc.pos[1] += (m_rc.size[1] - h) / 2;
break;
case valign_bottom:
m_rc.pos[1] += m_rc.size[1] - h;
break;
}
m_rc.size[1] = h;
}
/*
==============
GLabel::Draw
Render the text or picture
==============
*/
void GLabel::Draw()
{
doDraw(m_color[0], m_color[1], m_color[2], m_color[3]);
}
/*
==============
GLabel::GetDrawPoint
Retrieves the point at which the text is drawn - depends on alignment
==============
*/
void GLabel::GetDrawPoint(int *x, int *y)
{
int ofsx, ofsy;
int w, h;
int iw, ih;
w = m_rc.size[0] - m_iBorderX*2;
h = m_rc.size[1] - m_iBorderY*2;
ofsx = m_iBorderX;
ofsy = m_iBorderY;
GetIconSize(&iw, &ih);
if (iw > 0) {
w -= iw + 8;
ofsx += iw + 8;
}
switch(m_iAlign & halign_mask) {
default:
case halign_left: *x = 0; break;
case halign_center: *x = w / 2; break;
case halign_right: *x = w; break;
break;
}
*x += ofsx;
*x -= m_iScrollX;
switch(m_iAlign & valign_mask) {
default:
case valign_top: *y = 0; break;
case valign_center: *y = h / 2; break;
case valign_bottom: *y = h; break;
}
*y += ofsy;
*y -= m_iScrollY;
}
/*
==============
GLabel::doDraw
Put in its own function so derived classes can easily customize
the behaviour
==============
*/
void GLabel::doDraw(int r, int g, int b, int a)
{
int x, y;
int iw, ih;
GetDrawPoint(&x, &y);
if (m_pszText) {
if (m_pFont)
m_pFont->DrawString(x, y, m_pszText, m_iAlign, m_rc.size[0], m_iYSpacing,
r, g, b, a);
} else if (m_pPic) {
switch(m_iAlign & halign_mask) {
case halign_center: x -= m_pPic->size[0] / 2; break;
case halign_right: x -= m_pPic->size[0]; break;
}
switch(m_iAlign & valign_mask) {
case valign_center: y -= m_pPic->size[1] / 2; break;
case valign_bottom: y -= m_pPic->size[1]; break;
}
m_pPic->Draw(x, y, r, g, b, a);
} else if (m_pSprite) {
SPR_Draw(m_pSprite, x, y, -1, hal->framestart);
}
GetIconSize(&iw, &ih);
x = m_iBorderX + iw/2;
y = m_rc.size[1] / 2;
DrawIcon(x, y, r, g, b, a);
}
/*
==============
GLabel::GetCharRect
Return the enclosing rectangle for the given character
==============
*/
void GLabel::GetCharRect(int idx, LRect *rc)
{
int x, y;
GetDrawPoint(&x, &y);
if (!m_pszText || idx < 0) { // rc before the first char
rc->pos[0] = x;
rc->pos[1] = y;
switch(m_iAlign & valign_mask) {
case valign_center: rc->pos[1] -= 8; break;
case valign_bottom: rc->pos[1] -= 16; break;
}
rc->size[0] = 0;
rc->size[1] = 16;
} else {
m_pFont->CharRect(m_pszText, idx, m_iAlign, m_rc.size[0], m_iYSpacing, rc);
rc->pos[0] += x;
rc->pos[1] += y;
}
}
/*
==============
GLabel::GetIconSize
Return the size of the built-in icon (for radio-buttons)
==============
*/
void GLabel::GetIconSize(int *pw, int *ph)
{
*pw = 0; // normal labels don't have an icon
*ph = 0;
}
/*
==============
GLabel::DrawIcon
Draw the built-in icon (for radio-buttons)
==============
*/
void GLabel::DrawIcon(int x, int y, int r, int g, int b, int a)
{
}