add multi line string drawing (used in Input Dialog)

This commit is contained in:
Thomas Jentzsch 2019-08-07 15:17:19 +02:00
parent 0ab31bcec4
commit 7cd45ec32a
4 changed files with 101 additions and 3 deletions

View File

@ -309,6 +309,74 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::wrapString(const string inStr, int pos, string& leftStr, string& rightStr) const
{
int i;
for(i = pos; i > 0; --i)
{
if(isWhiteSpace(inStr[i]))
{
leftStr = inStr.substr(0, i);
if(inStr[i] == ' ') // skip leading space after line break
i++;
rightStr = inStr.substr(i);
return;
}
}
leftStr = inStr.substr(0, pos);
rightStr = inStr.substr(pos);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FBSurface::isWhiteSpace(const char s) const
{
const string WHITESPACES = " ,.;:+-";
int i;
for(i = 0; i < WHITESPACES.length(); ++i)
if(s == WHITESPACES[i])
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawString(const GUI::Font& font, const string& s,
int x, int y, int w, int h,
ColorId color, TextAlign align,
int deltax, bool useEllipsis, ColorId shadowColor)
{
string inStr = s;
// draw multiline string
while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2)
{
// String is too wide.
uInt32 i;
string leftStr, rightStr;
int w2 = 0;
// SLOW algorithm to find the acceptable length. But it is good enough for now.
for(i = 0; i < inStr.size(); ++i)
{
int charWidth = font.getCharWidth(inStr[i]);
if(w2 + charWidth > w)
break;
w2 += charWidth;
//str += inStr[i];
}
wrapString(inStr, i, leftStr, rightStr);
drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor);
h -= font.getFontHeight();
y += font.getFontHeight();
inStr = rightStr;
}
drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FBSurface::drawString(const GUI::Font& font, const string& s,
int x, int y, int w,

View File

@ -203,6 +203,26 @@ class FBSurface
virtual void frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
ColorId color, FrameStyle style = FrameStyle::Solid);
/**
This method should be called to draw the specified string.
@param font The font to draw the string with
@param s The string to draw
@param x The x coordinate
@param y The y coordinate
@param w The width of the string area
@param h The height of the string area (for multi line strings)
@param color The color of the text
@param align The alignment of the text in the string width area
@param deltax FIXME
@param useEllipsis Whether to use '...' when the string is too long
*/
virtual void drawString(
const GUI::Font& font, const string& s, int x, int y, int w, int h,
ColorId color, TextAlign align = TextAlign::Left,
int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone);
/**
This method should be called to draw the specified string.
@ -344,6 +364,15 @@ class FBSurface
*/
bool checkBounds(const uInt32 x, const uInt32 y) const;
void wrapString(const string inStr, int pos, string& leftStr, string& rightStr) const;
/**
Check if the given character is a whitespace.
@param c Character to check
@return True if whitespace character
*/
bool isWhiteSpace(const char s) const;
protected:
static const uInt32* myPalette;
uInt32* myPixels;

View File

@ -93,7 +93,7 @@ void EditTextWidget::drawWidget(bool hilite)
// Draw the text
adjustOffset();
s.drawString(_font, editString(), _x + 2, _y + 2, getEditRect().w(),
s.drawString(_font, editString(), _x + 2, _y + 2, getEditRect().w(), getEditRect().h(),
_changed && onTop && isEnabled()
? kDbgChangedTextColor
: onTop && isEnabled() ? _textcolor : kColor,

View File

@ -56,10 +56,11 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
buttonHeight = font.getLineHeight() + 4;
const int HBORDER = 8;
const int VBORDER = 8;
const int ACTION_LINES = 2;
int xpos = HBORDER, ypos = VBORDER;
myActionsList = new StringListWidget(boss, font, xpos, ypos,
_w - buttonWidth - HBORDER * 2 - 8, _h - 3*lineHeight - VBORDER);
_w - buttonWidth - HBORDER * 2 - 8, _h - (2 + ACTION_LINES) * lineHeight - VBORDER);
myActionsList->setTarget(this);
myActionsList->setEditable(false);
myActionsList->setList(actions);
@ -117,7 +118,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
fontHeight, "Action", TextAlign::Left);
myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 8, ypos,
_w - xpos - t->getWidth() - 8 - HBORDER, lineHeight, "");
_w - xpos - t->getWidth() - 8 - HBORDER, lineHeight * ACTION_LINES, "");
myKeyMapping->setEditable(false, true);
myKeyMapping->clearFlags(Widget::FLAG_RETAIN_FOCUS);
}