snes9xgx/source/ngc/gui/gui_text.cpp

347 lines
6.6 KiB
C++
Raw Normal View History

2009-03-11 18:28:37 +01:00
/****************************************************************************
2009-04-10 10:12:37 +02:00
* libwiigui
2009-03-11 18:28:37 +01:00
*
2009-04-10 10:12:37 +02:00
* Tantric 2009
2009-03-11 18:28:37 +01:00
*
* gui_text.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static int currentSize = 0;
2009-03-16 06:16:20 +01:00
static int presetSize = 0;
static int presetMaxWidth = 0;
static int presetAlignmentHor = 0;
static int presetAlignmentVert = 0;
static u16 presetStyle = 0;
static GXColor presetColor = (GXColor){255, 255, 255, 255};
2009-03-11 18:28:37 +01:00
#define TEXT_SCROLL_DELAY 8
#define TEXT_SCROLL_INITIAL_DELAY 6
2009-03-11 18:28:37 +01:00
/**
* Constructor for the GuiText class.
*/
GuiText::GuiText(const char * t, int s, GXColor c)
{
origText = NULL;
2009-03-11 18:28:37 +01:00
text = NULL;
size = s;
color = c;
alpha = c.a;
style = FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE;
2009-03-16 06:16:20 +01:00
maxWidth = 0;
wrap = false;
textDyn = NULL;
textScroll = SCROLL_NONE;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY;
2009-03-11 18:28:37 +01:00
alignmentHor = ALIGN_CENTRE;
alignmentVert = ALIGN_MIDDLE;
if(t)
{
origText = strdup(t);
2009-03-16 06:16:20 +01:00
text = fontSystem->charToWideChar((char *)t);
}
2009-03-16 06:16:20 +01:00
}
/**
* Constructor for the GuiText class, uses presets
*/
GuiText::GuiText(const char * t)
{
origText = NULL;
2009-03-16 06:16:20 +01:00
text = NULL;
size = presetSize;
color = presetColor;
alpha = presetColor.a;
style = presetStyle;
maxWidth = presetMaxWidth;
wrap = false;
textDyn = NULL;
textScroll = SCROLL_NONE;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY;
2009-03-16 06:16:20 +01:00
alignmentHor = presetAlignmentHor;
alignmentVert = presetAlignmentVert;
if(t)
{
origText = strdup(t);
2009-03-16 06:16:20 +01:00
text = fontSystem->charToWideChar((char *)t);
}
2009-03-11 18:28:37 +01:00
}
/**
* Destructor for the GuiText class.
*/
GuiText::~GuiText()
{
if(origText)
free(origText);
2009-03-11 18:28:37 +01:00
if(text)
delete text;
if(textDyn)
delete textDyn;
2009-03-11 18:28:37 +01:00
}
void GuiText::SetText(const char * t)
{
if(origText)
free(origText);
2009-03-11 18:28:37 +01:00
if(text)
delete text;
if(textDyn)
delete textDyn;
2009-03-11 18:28:37 +01:00
origText = NULL;
2009-03-11 18:28:37 +01:00
text = NULL;
textDyn = NULL;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
2009-03-11 18:28:37 +01:00
if(t)
{
origText = strdup(t);
2009-03-16 06:16:20 +01:00
text = fontSystem->charToWideChar((char *)t);
}
2009-03-11 18:28:37 +01:00
}
2009-03-16 06:16:20 +01:00
void GuiText::SetPresets(int sz, GXColor c, int w, u16 s, int h, int v)
{
presetSize = sz;
presetColor = c;
presetStyle = s;
presetMaxWidth = w;
presetAlignmentHor = h;
presetAlignmentVert = v;
}
void GuiText::SetFontSize(int s)
2009-03-11 18:28:37 +01:00
{
size = s;
}
2009-03-16 06:16:20 +01:00
void GuiText::SetMaxWidth(int width)
{
maxWidth = width;
}
void GuiText::SetWrap(bool w, int width)
2009-03-16 06:16:20 +01:00
{
wrap = w;
maxWidth = width;
}
void GuiText::SetScroll(int s)
{
if(textScroll == s)
return;
if(textDyn)
{
delete(textDyn);
textDyn = NULL;
}
textScroll = s;
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
textScrollDelay = TEXT_SCROLL_DELAY;
2009-03-16 06:16:20 +01:00
}
2009-03-11 18:28:37 +01:00
void GuiText::SetColor(GXColor c)
{
color = c;
alpha = c.a;
}
2009-03-16 06:16:20 +01:00
2009-03-11 18:28:37 +01:00
void GuiText::SetStyle(u16 s)
{
style = s;
}
void GuiText::SetAlignment(int hor, int vert)
{
style = 0;
switch(hor)
{
case ALIGN_LEFT:
style |= FTGX_JUSTIFY_LEFT;
break;
case ALIGN_RIGHT:
style |= FTGX_JUSTIFY_RIGHT;
break;
default:
style |= FTGX_JUSTIFY_CENTER;
break;
}
switch(vert)
{
case ALIGN_TOP:
style |= FTGX_ALIGN_TOP;
break;
case ALIGN_BOTTOM:
style |= FTGX_ALIGN_BOTTOM;
break;
default:
style |= FTGX_ALIGN_MIDDLE;
break;
}
alignmentHor = hor;
alignmentVert = vert;
}
/**
* Draw the text on screen
*/
void GuiText::Draw()
{
if(!text)
return;
if(!this->IsVisible())
return;
GXColor c = color;
c.a = this->GetAlpha();
2009-03-16 06:16:20 +01:00
int newSize = size*this->GetScale();
if(newSize != currentSize)
2009-03-11 18:28:37 +01:00
{
2009-03-16 06:16:20 +01:00
fontSystem->changeSize(newSize);
currentSize = newSize;
2009-03-11 18:28:37 +01:00
}
2009-03-16 06:16:20 +01:00
int voffset = 0;
if(alignmentVert == ALIGN_MIDDLE)
voffset = -newSize/2 + 2;
if(maxWidth > 0)
2009-03-16 06:16:20 +01:00
{
char * tmpText = strdup(origText);
u8 maxChar = (maxWidth*2.0) / newSize;
if(!textDyn)
2009-03-16 06:16:20 +01:00
{
if(strlen(tmpText) > maxChar)
tmpText[maxChar] = 0;
textDyn = fontSystem->charToWideChar(tmpText);
}
2009-03-16 06:16:20 +01:00
if(textScroll == SCROLL_HORIZONTAL)
{
int textlen = strlen(origText);
2009-03-16 06:16:20 +01:00
if(textlen > maxChar && (FrameTimer % textScrollDelay == 0))
2009-03-16 06:16:20 +01:00
{
if(textScrollInitialDelay)
2009-03-16 06:16:20 +01:00
{
textScrollInitialDelay--;
}
else
{
textScrollPos++;
if(textScrollPos > textlen-1)
{
textScrollPos = 0;
textScrollInitialDelay = TEXT_SCROLL_INITIAL_DELAY;
}
strncpy(tmpText, &origText[textScrollPos], maxChar-1);
tmpText[maxChar-1] = 0;
int dynlen = strlen(tmpText);
if(dynlen+2 < maxChar)
{
tmpText[dynlen] = ' ';
tmpText[dynlen+1] = ' ';
strncat(&tmpText[dynlen+2], origText, maxChar - dynlen - 2);
}
if(textDyn) delete textDyn;
textDyn = fontSystem->charToWideChar(tmpText);
}
}
if(textDyn)
fontSystem->drawText(this->GetLeft(), this->GetTop()+voffset, textDyn, c, style);
}
else if(wrap)
{
int lineheight = newSize + 6;
int txtlen = wcslen(text);
int i = 0;
int ch = 0;
int linenum = 0;
int lastSpace = -1;
int lastSpaceIndex = -1;
wchar_t * textrow[20];
while(ch < txtlen)
{
if(i == 0)
textrow[linenum] = new wchar_t[txtlen + 1];
textrow[linenum][i] = text[ch];
textrow[linenum][i+1] = 0;
if(text[ch] == ' ' || ch == txtlen-1)
{
if(wcslen(textrow[linenum]) >= maxChar)
2009-03-16 06:16:20 +01:00
{
if(lastSpace >= 0)
{
textrow[linenum][lastSpaceIndex] = 0; // discard space, and everything after
ch = lastSpace; // go backwards to the last space
lastSpace = -1; // we have used this space
lastSpaceIndex = -1;
}
linenum++;
i = -1;
}
else if(ch == txtlen-1)
{
linenum++;
2009-03-16 06:16:20 +01:00
}
}
if(text[ch] == ' ' && i >= 0)
2009-03-16 06:16:20 +01:00
{
lastSpace = ch;
lastSpaceIndex = i;
2009-03-16 06:16:20 +01:00
}
ch++;
i++;
2009-03-16 06:16:20 +01:00
}
if(alignmentVert == ALIGN_MIDDLE)
voffset = voffset - (lineheight*linenum)/2 + lineheight/2;
for(i=0; i < linenum; i++)
2009-03-16 06:16:20 +01:00
{
fontSystem->drawText(this->GetLeft(), this->GetTop()+voffset+i*lineheight, textrow[i], c, style);
delete textrow[i];
2009-03-16 06:16:20 +01:00
}
}
else
2009-03-16 06:16:20 +01:00
{
fontSystem->drawText(this->GetLeft(), this->GetTop()+voffset, textDyn, c, style);
2009-03-16 06:16:20 +01:00
}
free(tmpText);
2009-03-16 06:16:20 +01:00
}
else
{
fontSystem->drawText(this->GetLeft(), this->GetTop()+voffset, text, c, style);
}
2009-03-11 18:28:37 +01:00
this->UpdateEffects();
}