Added automatic word wrapping to the about scroller

svn-id: r18145
This commit is contained in:
Max Horn 2005-05-17 23:41:35 +00:00
parent e0ddf7480a
commit e05da91674
4 changed files with 83 additions and 77 deletions

@ -31,10 +31,7 @@ namespace GUI {
enum { enum {
kScrollStartDelay = 1500, kScrollStartDelay = 1500,
kScrollMillisPerPixel = 80, kScrollMillisPerPixel = 80
kXOff = 3,
kYOff = 2
}; };
// The following commands can be put at the start of a line (all subject to change): // The following commands can be put at the start of a line (all subject to change):
@ -45,6 +42,9 @@ enum {
// 2 light border (light gray) // 2 light border (light gray)
// 3 dark border (dark gray) // 3 dark border (dark gray)
// 4 background (black) // 4 background (black)
// TODO: Maybe add a tab/indent feature; that is, make it possible to specify
// an amount by which that line shall be indented (the indent of course would have
// to be considered while performing any word wrapping, too).
static const char *credits_intro[] = { static const char *credits_intro[] = {
"\\C""Copyright (C) 2002-2005 The ScummVM project", "\\C""Copyright (C) 2002-2005 The ScummVM project",
"\\C""http://www.scummvm.org", "\\C""http://www.scummvm.org",
@ -57,25 +57,11 @@ static const char *credits_intro[] = {
"\\C""Flight of the Amazon Queen (C) John Passfield", "\\C""Flight of the Amazon Queen (C) John Passfield",
"\\C""and Steve Stamatiadis", "\\C""and Steve Stamatiadis",
"\\C""", "\\C""",
"\\C""This program is free software; you can", "\\C""This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.",
"\\C""redistribute it and/or modify it under the",
"\\C""terms of the GNU General Public License as",
"\\C""published by the Free Software Foundation;",
"\\C""either version 2 of the License, or (at your",
"\\C""option) any later version.",
"\\C""", "\\C""",
"\\C""This program is distributed in the hope that", "\\C""This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.",
"\\C""it will be useful, but WITHOUT ANY WARRANTY;",
"\\C""without even the implied warranty of",
"\\C""MERCHANTABILITY or FITNESS FOR A PARTICULAR",
"\\C""PURPOSE. See the GNU General Public License",
"\\C""for more details.",
"\\C""", "\\C""",
"\\C""You should have received a copy of the GNU", "\\C""You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.",
"\\C""General Public License along with this",
"\\C""program; if not, write to the Free Software",
"\\C""Foundation, Inc., 59 Temple Place - Suite 330,",
"\\C""Boston, MA 02111-1307, USA.",
"\\C""" "\\C"""
}; };
@ -91,17 +77,37 @@ AboutDialog::AboutDialog()
const int screenW = g_system->getOverlayWidth(); const int screenW = g_system->getOverlayWidth();
const int screenH = g_system->getOverlayHeight(); const int screenH = g_system->getOverlayHeight();
_w = screenW - 2 * 10; int outerBorder;
_h = screenH - 20 - 16;
if (_w >= 400 && _h >= 300) { if (screenW >= 400 && screenH >= 300) {
_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont); _font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
xOff = 8;
yOff = 5;
outerBorder = 80;
} else { } else {
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont); _font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
xOff = 3;
yOff = 2;
outerBorder = 10;
} }
_w = screenW - 2 * outerBorder;
_h = screenH - 2 * outerBorder;
_lineHeight = _font->getFontHeight() + 3; _lineHeight = _font->getFontHeight() + 3;
// Heuristic to compute 'optimal' dialog width
int maxW = _w - 2*xOff;
_w = 0;
for (i = 0; i < ARRAYSIZE(credits); i++) {
int tmp = _font->getStringWidth(credits[i]+5);
if ( _w < tmp && tmp <= maxW) {
_w = tmp;
}
}
_w += 2*xOff;
for (i = 0; i < 1; i++) for (i = 0; i < 1; i++)
_lines.push_back(""); _lines.push_back("");
@ -114,43 +120,57 @@ AboutDialog::AboutDialog()
date += ')'; date += ')';
_lines.push_back(date); _lines.push_back(date);
Common::String features("Supports: "); Common::String features("\\C\\c2""Supports: ");
features += gScummVMFeatures; features += gScummVMFeatures;
addLine(features.c_str());
// If the features string is too wide, split it up
const int maxWidth = _w - 2*kXOff;
if (_font->getStringWidth(features) > maxWidth) {
Common::StringList wrappedLines;
_font->wordWrapText(features, maxWidth, wrappedLines);
for (i = 0; i < (int)wrappedLines.size(); ++i)
_lines.push_back("\\C\\c2" + wrappedLines[i]);
} else
_lines.push_back("\\C\\c2" + features);
_lines.push_back(""); _lines.push_back("");
for (i = 0; i < ARRAYSIZE(credits_intro); i++) for (i = 0; i < ARRAYSIZE(credits_intro); i++)
_lines.push_back(credits_intro[i]); addLine(credits_intro[i]);
for (i = 0; i < ARRAYSIZE(credits); i++) for (i = 0; i < ARRAYSIZE(credits); i++)
_lines.push_back(credits[i]); addLine(credits[i]);
// Compute 'optimal' dialog width
int maxW = _w;
_w = 0;
for (i = 0; i < (int)_lines.size(); ++i) {
_w = MAX(_w, _font->getStringWidth(_lines[i]));
}
if (_w > maxW)
_w = maxW;
// Center the dialog // Center the dialog
_x = (screenW - _w) / 2; _x = (screenW - _w) / 2;
_y = (screenH - _h) / 2; _y = (screenH - _h) / 2;
} }
void AboutDialog::addLine(const char *str) {
// Extract formatting instructions
Common::String format;
while (*str == '\\') {
format += *str++;
switch (*str) {
case 'C':
case 'L':
case 'R':
format += *str++;
break;
case 'c':
format += *str++;
format += *str++;
break;
default:
error("Unknown scroller opcode '%c'\n", *str);
break;
}
}
if (*str == 0) {
_lines.push_back(format);
} else {
Common::StringList wrappedLines;
_font->wordWrapText(str, _w - 2*xOff, wrappedLines);
for (Common::StringList::const_iterator i = wrappedLines.begin(); i != wrappedLines.end(); ++i) {
_lines.push_back(format + *i);
}
}
}
void AboutDialog::open() { void AboutDialog::open() {
_scrollTime = getMillis() + kScrollStartDelay; _scrollTime = getMillis() + kScrollStartDelay;
_scrollPos = 0; _scrollPos = 0;
@ -185,7 +205,7 @@ void AboutDialog::drawDialog() {
// in the right way. Should be even faster... // in the right way. Should be even faster...
const int firstLine = _scrollPos / _lineHeight; const int firstLine = _scrollPos / _lineHeight;
const int lastLine = MIN((_scrollPos + _h) / _lineHeight + 1, (uint32)_lines.size()); const int lastLine = MIN((_scrollPos + _h) / _lineHeight + 1, (uint32)_lines.size());
int y = _y + kYOff - (_scrollPos % _lineHeight); int y = _y + yOff - (_scrollPos % _lineHeight);
for (int line = firstLine; line < lastLine; line++) { for (int line = firstLine; line < lastLine; line++) {
const char *str = _lines[line].c_str(); const char *str = _lines[line].c_str();
@ -220,12 +240,12 @@ void AboutDialog::drawDialog() {
color = g_gui._bgcolor; color = g_gui._bgcolor;
break; break;
default: default:
warning("Unknown color type '%c'", str[2]); error("Unknown color type '%c'", str[2]);
} }
str++; str++;
break; break;
default: default:
warning("Unknown scroller opcode '%c'\n", str[1]); error("Unknown scroller opcode '%c'\n", str[1]);
break; break;
} }
str += 2; str += 2;
@ -235,7 +255,7 @@ void AboutDialog::drawDialog() {
while (*str && *str == ' ') while (*str && *str == ' ')
str++; str++;
_font->drawString(&g_gui.getScreen(), str, _x + kXOff, y, _w - 2 * kXOff, color, align, 0, false); _font->drawString(&g_gui.getScreen(), str, _x + xOff, y, _w - 2 * xOff, color, align, 0, false);
y += _lineHeight; y += _lineHeight;
} }

@ -43,6 +43,10 @@ protected:
Graphics::Surface _canvas; Graphics::Surface _canvas;
const Graphics::Font *_font; const Graphics::Font *_font;
int xOff, yOff;
void addLine(const char *str);
public: public:
AboutDialog(); AboutDialog();

@ -106,8 +106,7 @@ static const char *credits[] = {
"\\L\\c0"" Juha Niemimaki", "\\L\\c0"" Juha Niemimaki",
"\\L\\c2"" AmigaOS 4 port maintaining", "\\L\\c2"" AmigaOS 4 port maintaining",
"\\L\\c0""", "\\L\\c0""",
"\\L\\c0""And to all the contributors, users, and beta", "\\L\\c0""And to all the contributors, users, and beta testers we've missed. Thanks!",
"\\L\\c0""testers we've missed. Thanks!",
"\\L\\c0""", "\\L\\c0""",
"\\C\\c1""Special thanks to:", "\\C\\c1""Special thanks to:",
"\\L\\c0"" Sander Buskens", "\\L\\c0"" Sander Buskens",
@ -133,27 +132,12 @@ static const char *credits[] = {
"\\L\\c2"" For additional work on the original MT-32", "\\L\\c2"" For additional work on the original MT-32",
"\\L\\c2"" emulator", "\\L\\c2"" emulator",
"\\L\\c0""", "\\L\\c0""",
"\\L\\c0""Tony Warriner and everyone at Revolution", "\\L\\c0""Tony Warriner and everyone at Revolution Software Ltd. for sharing with us the source of some of their brilliant games, allowing us to release Beneath a Steel Sky as freeware... and generally being supportive above and beyond the call of duty.",
"\\L\\c0""Software Ltd. for sharing with us the source",
"\\L\\c0""of some of their brilliant games, allowing us",
"\\L\\c0""to release Beneath a Steel Sky as freeware...",
"\\L\\c0""and generally being supportive above and",
"\\L\\c0""beyond the call of duty.",
"\\L\\c0""", "\\L\\c0""",
"\\L\\c0""John Passfield and Steve Stamatiadis for", "\\L\\c0""John Passfield and Steve Stamatiadis for sharing the source of their classic title, Flight of the Amazon Queen and also being incredibly supportive.",
"\\L\\c0""sharing the source of their classic title,",
"\\L\\c0""Flight of the Amazon Queen and also being",
"\\L\\c0""incredibly supportive.",
"\\L\\c0""", "\\L\\c0""",
"\\L\\c0""Joe Pearce from The Wyrmkeep Entertainment", "\\L\\c0""Joe Pearce from The Wyrmkeep Entertainment Co. for sharing the source of their famous title Inherit the Earth and always prompt replies to our questions.",
"\\L\\c0""Co. for sharing the source of their famous",
"\\L\\c0""title Inherit the Earth and always prompt",
"\\L\\c0""replies to our questions.",
"\\L\\c0""", "\\L\\c0""",
"\\L\\c0""Aric Wilmunder, Ron Gilbert, David Fox, Vince", "\\L\\c0""Aric Wilmunder, Ron Gilbert, David Fox, Vince Lee, and all those at LucasFilm/LucasArts who made SCUMM the insane mess to reimplement that it is today. Feel free to drop us a line and tell us what you think, guys!",
"\\L\\c0""Lee, and all those at LucasFilm/LucasArts who",
"\\L\\c0""made SCUMM the insane mess to reimplement",
"\\L\\c0""that it is today. Feel free to drop us a line",
"\\L\\c0""and tell us what you think, guys!",
"\\L\\c0""", "\\L\\c0""",
}; };

@ -297,10 +297,8 @@ sub add_paragraph {
} elsif ($mode eq "CPP") { } elsif ($mode eq "CPP") {
my $line_start = '"\\\\L\\\\c0""'; my $line_start = '"\\\\L\\\\c0""';
my $line_end = '",'; my $line_end = '",';
$Text::Wrap::separator = $line_end . "\n" . $line_start; print $line_start . $text . $line_end . "\n";
print $line_start . wrap("", "", $text) . $line_end . "\n";
print $line_start . $line_end . "\n"; print $line_start . $line_end . "\n";
$Text::Wrap::separator = "\n";
} elsif ($mode eq "XML") { } elsif ($mode eq "XML") {
print " <row><entry namest='start' nameend='job'>" . $text . "</entry></row>\n"; print " <row><entry namest='start' nameend='job'>" . $text . "</entry></row>\n";
print " <row><entry namest='start' nameend='job'> </entry></row>\n\n"; print " <row><entry namest='start' nameend='job'> </entry></row>\n\n";