mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-09-08 00:23:19 +02:00
351 lines
6.3 KiB
C++
351 lines
6.3 KiB
C++
![]() |
#include "Text.hpp"
|
||
|
|
||
|
Text::Text(const char * t, int s, GXColor c)
|
||
|
: GuiText(t, s, c)
|
||
|
{
|
||
|
maxWidth = 400;
|
||
|
linestodraw = 9;
|
||
|
curLineStart = 0;
|
||
|
FirstLineOffset = 0;
|
||
|
wText = NULL;
|
||
|
|
||
|
if(!text)
|
||
|
return;
|
||
|
|
||
|
wText = new (std::nothrow) wString(text);
|
||
|
if(!wText)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(wText->size() == 0)
|
||
|
{
|
||
|
wText->push_back(L' ');
|
||
|
wText->push_back(0);
|
||
|
}
|
||
|
|
||
|
textWidth = (font ? font : fontSystem)->getWidth(wText->data(), currentSize);
|
||
|
delete [] text;
|
||
|
text = NULL;
|
||
|
|
||
|
SetMaxWidth(maxWidth);
|
||
|
}
|
||
|
|
||
|
Text::Text(const wchar_t * t, int s, GXColor c)
|
||
|
: GuiText((wchar_t *) NULL, s, c)
|
||
|
{
|
||
|
maxWidth = 400;
|
||
|
linestodraw = 9;
|
||
|
curLineStart = 0;
|
||
|
FirstLineOffset = 0;
|
||
|
wText = NULL;
|
||
|
|
||
|
if(!t)
|
||
|
return;
|
||
|
|
||
|
wText = new (std::nothrow) wString(t);
|
||
|
if(!wText)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(wText->size() == 0)
|
||
|
{
|
||
|
wText->push_back(L' ');
|
||
|
wText->push_back(0);
|
||
|
}
|
||
|
|
||
|
textWidth = (font ? font : fontSystem)->getWidth(wText->data(), currentSize);
|
||
|
|
||
|
SetMaxWidth(maxWidth);
|
||
|
}
|
||
|
|
||
|
Text::~Text()
|
||
|
{
|
||
|
if(wText)
|
||
|
delete wText;
|
||
|
wText = NULL;
|
||
|
|
||
|
TextLines.clear();
|
||
|
ClearDynamicText();
|
||
|
}
|
||
|
|
||
|
void Text::SetText(const char * t)
|
||
|
{
|
||
|
wchar_t * tmp = charToWideChar(t);
|
||
|
if(!tmp)
|
||
|
return;
|
||
|
|
||
|
if(wText)
|
||
|
delete wText;
|
||
|
|
||
|
wText = new (std::nothrow) wString(tmp);
|
||
|
if(!wText)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(wText->size() == 0)
|
||
|
{
|
||
|
wText->push_back(L' ');
|
||
|
wText->push_back(0);
|
||
|
}
|
||
|
|
||
|
textWidth = (font ? font : fontSystem)->getWidth(wText->data(), currentSize);
|
||
|
|
||
|
delete [] tmp;
|
||
|
|
||
|
ClearDynamicText();
|
||
|
CalcLineOffsets();
|
||
|
}
|
||
|
|
||
|
void Text::SetText(const wchar_t * t)
|
||
|
{
|
||
|
if(!t)
|
||
|
return;
|
||
|
|
||
|
if(wText)
|
||
|
delete wText;
|
||
|
|
||
|
wText = new wString(t);
|
||
|
textWidth = (font ? font : fontSystem)->getWidth(wText->data(), currentSize);
|
||
|
CalcLineOffsets();
|
||
|
}
|
||
|
|
||
|
void Text::SetMaxWidth(int w)
|
||
|
{
|
||
|
maxWidth = w;
|
||
|
curLineStart = 0;
|
||
|
Refresh();
|
||
|
}
|
||
|
|
||
|
void Text::SetTextLine(int line)
|
||
|
{
|
||
|
if(line < 0)
|
||
|
line = 0;
|
||
|
else if(line > (int) TextLines.size()-1)
|
||
|
line = TextLines.size()-1;
|
||
|
|
||
|
curLineStart = line;
|
||
|
|
||
|
FillRows();
|
||
|
|
||
|
while((int) textDyn.size() < linestodraw && curLineStart > 0)
|
||
|
{
|
||
|
PreviousLine();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Text::SetTextPos(int pos)
|
||
|
{
|
||
|
if(!wText)
|
||
|
return;
|
||
|
|
||
|
int diff = 10000;
|
||
|
|
||
|
for(u32 i = 0; i < TextLines.size(); i++)
|
||
|
{
|
||
|
int curDiff = abs(TextLines[i].LineOffset - pos);
|
||
|
if(curDiff < diff)
|
||
|
{
|
||
|
diff = curDiff;
|
||
|
curLineStart = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FillRows();
|
||
|
|
||
|
while((int) textDyn.size() < linestodraw && curLineStart > 0)
|
||
|
{
|
||
|
PreviousLine();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const wchar_t * Text::GetText()
|
||
|
{
|
||
|
return wText->c_str();
|
||
|
}
|
||
|
|
||
|
std::string Text::GetUTF8String(void) const
|
||
|
{
|
||
|
return wText->toUTF8();
|
||
|
}
|
||
|
|
||
|
int Text::GetLineOffset(int ind)
|
||
|
{
|
||
|
if(TextLines.size() == 0)
|
||
|
return 0;
|
||
|
|
||
|
if(ind < 0)
|
||
|
return TextLines[0].LineOffset;
|
||
|
|
||
|
if(ind >= (int) TextLines.size()-1)
|
||
|
return TextLines[TextLines.size()-1].LineOffset;
|
||
|
|
||
|
return TextLines[ind].LineOffset;
|
||
|
}
|
||
|
|
||
|
const wchar_t * Text::GetTextLine(int ind)
|
||
|
{
|
||
|
if(filling || textDyn.size() == 0)
|
||
|
return NULL;
|
||
|
|
||
|
if(ind < 0)
|
||
|
return textDyn[0];
|
||
|
|
||
|
if(ind >= (int) textDyn.size())
|
||
|
return textDyn[textDyn.size()-1];
|
||
|
|
||
|
return textDyn[ind];
|
||
|
}
|
||
|
|
||
|
void Text::Refresh()
|
||
|
{
|
||
|
CalcLineOffsets();
|
||
|
FillRows();
|
||
|
}
|
||
|
|
||
|
void Text::NextLine()
|
||
|
{
|
||
|
if(!wText || (curLineStart+1 > ((int) TextLines.size()-linestodraw)))
|
||
|
return;
|
||
|
|
||
|
++curLineStart;
|
||
|
|
||
|
FillRows();
|
||
|
}
|
||
|
|
||
|
void Text::PreviousLine()
|
||
|
{
|
||
|
if(!wText || curLineStart-1 < 0)
|
||
|
return;
|
||
|
|
||
|
--curLineStart;
|
||
|
|
||
|
FillRows();
|
||
|
}
|
||
|
|
||
|
void Text::FillRows()
|
||
|
{
|
||
|
if(!wText)
|
||
|
return;
|
||
|
|
||
|
filling = true;
|
||
|
|
||
|
ClearDynamicText();
|
||
|
|
||
|
for(int i = 0; i < linestodraw && i < (int) TextLines.size(); i++)
|
||
|
{
|
||
|
if(i >= (int) textDyn.size())
|
||
|
{
|
||
|
textDyn.resize(i+1);
|
||
|
textDyn[i] = new wchar_t[maxWidth];
|
||
|
}
|
||
|
int offset = TextLines[curLineStart+i].LineOffset;
|
||
|
int count = TextLines[curLineStart+i].CharCount+1;
|
||
|
|
||
|
for(int n = 0; n < count && offset+n < (int) wText->size(); n++)
|
||
|
textDyn[i][n] = wText->at(offset+n);
|
||
|
|
||
|
textDyn[i][count] = 0;
|
||
|
}
|
||
|
|
||
|
filling = false;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void Text::CalcLineOffsets()
|
||
|
{
|
||
|
if(!wText)
|
||
|
return;
|
||
|
|
||
|
TextLines.clear();
|
||
|
|
||
|
TextLine TmpLine;
|
||
|
TmpLine.CharCount = 0;
|
||
|
TmpLine.LineOffset = 0;
|
||
|
TmpLine.width = 0;
|
||
|
|
||
|
const wchar_t * origTxt = wText->c_str();
|
||
|
int ch = 0;
|
||
|
int lastSpace = -1;
|
||
|
int lastSpaceIndex = -1;
|
||
|
int currWidth = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
while(origTxt[ch])
|
||
|
{
|
||
|
currWidth += fontSystem->getCharWidth(origTxt[ch], currentSize, ch > 0 ? origTxt[ch-1] : 0x0000);
|
||
|
|
||
|
if(currWidth >= maxWidth)
|
||
|
{
|
||
|
if(lastSpace > 0)
|
||
|
{
|
||
|
ch = lastSpace;
|
||
|
}
|
||
|
TmpLine.CharCount = ch-TmpLine.LineOffset;
|
||
|
TmpLine.width = currWidth;
|
||
|
TextLines.push_back(TmpLine);
|
||
|
currWidth = 0;
|
||
|
lastSpace = -1;
|
||
|
i = -1;
|
||
|
TmpLine.LineOffset = ch+1;
|
||
|
}
|
||
|
else if(origTxt[ch] == '\n')
|
||
|
{
|
||
|
TmpLine.CharCount = ch-TmpLine.LineOffset;
|
||
|
TmpLine.width = currWidth;
|
||
|
TextLines.push_back(TmpLine);
|
||
|
currWidth = 0;
|
||
|
lastSpace = -1;
|
||
|
i = -1;
|
||
|
TmpLine.LineOffset = ch+1;
|
||
|
}
|
||
|
else if(origTxt[ch] == ' ')
|
||
|
{
|
||
|
lastSpace = ch;
|
||
|
lastSpaceIndex = i;
|
||
|
}
|
||
|
|
||
|
ch++;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
TmpLine.CharCount = ch-TmpLine.LineOffset;
|
||
|
TmpLine.width = currWidth;
|
||
|
|
||
|
if(TmpLine.CharCount > 0)
|
||
|
TextLines.push_back(TmpLine);
|
||
|
}
|
||
|
|
||
|
void Text::Draw()
|
||
|
{
|
||
|
if(textDyn.size() == 0)
|
||
|
return;
|
||
|
|
||
|
if(!this->IsVisible())
|
||
|
return;
|
||
|
|
||
|
GXColor c = color;
|
||
|
c.a = this->GetAlpha();
|
||
|
|
||
|
int newSize = size*GetScale();
|
||
|
|
||
|
if(newSize != currentSize)
|
||
|
{
|
||
|
currentSize = newSize;
|
||
|
|
||
|
if(wText)
|
||
|
textWidth = (font ? font : fontSystem)->getWidth(wText->data(), currentSize);
|
||
|
}
|
||
|
|
||
|
u16 lineheight = newSize + 6;
|
||
|
|
||
|
for(u32 i = 0; i < textDyn.size(); i++)
|
||
|
{
|
||
|
if(!filling)
|
||
|
(font ? font : fontSystem)->drawText(this->GetLeft(), this->GetTop()+i*lineheight, 0, textDyn[i], currentSize, c, style, 0, maxWidth);
|
||
|
}
|
||
|
}
|