summaryrefslogtreecommitdiff
path: root/src/gui/browserbox.cpp
diff options
context:
space:
mode:
authorBjörn Steinbrink <B.Steinbrink@gmx.de>2007-09-21 03:58:07 +0000
committerIra Rice <irarice@gmail.com>2009-01-05 20:21:28 -0700
commit77db175ceabe8d05665191835d0250a927d93d32 (patch)
tree1dc69120e9455c30bc2ec36b2aa9bb63ae2f1295 /src/gui/browserbox.cpp
parentfde40d91bceb1c7e7818d898f8731089ff87a9f4 (diff)
downloadmana-client-77db175ceabe8d05665191835d0250a927d93d32.tar.gz
mana-client-77db175ceabe8d05665191835d0250a927d93d32.tar.bz2
mana-client-77db175ceabe8d05665191835d0250a927d93d32.tar.xz
mana-client-77db175ceabe8d05665191835d0250a927d93d32.zip
Refactor the way in which browser box text is drawn and wrapped.
(cherry picked from mainline commit ecabe82d8720689905a6d035b0597d97037287c7) Conflicts: src/gui/browserbox.cpp
Diffstat (limited to 'src/gui/browserbox.cpp')
-rw-r--r--src/gui/browserbox.cpp215
1 files changed, 127 insertions, 88 deletions
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp
index 18acfa6a..1441109f 100644
--- a/src/gui/browserbox.cpp
+++ b/src/gui/browserbox.cpp
@@ -21,14 +21,10 @@
#include <algorithm>
-#include <guichan/graphics.hpp>
-#include <guichan/imagefont.hpp>
-#include <guichan/mouseinput.hpp>
-
#include "browserbox.h"
-#include "colour.h"
#include "linkhandler.h"
+#include "../graphics.h"
#include "../sdltruetypefont.hpp"
BrowserBox::BrowserBox(unsigned int mode):
@@ -73,7 +69,7 @@ void BrowserBox::addRow(const std::string &row)
std::string newRow;
BROWSER_LINK bLink;
int idx1, idx2, idx3;
- gcn::Font *font = getFont();
+ gcn::contrib::SDLTrueTypeFont *font = static_cast<gcn::contrib::SDLTrueTypeFont*>(getFont());
// Use links and user defined colors
if (mUseLinksAndUserColors)
@@ -103,12 +99,12 @@ void BrowserBox::addRow(const std::string &row)
mLinks.push_back(bLink);
- newRow += "##<" + bLink.caption;
+ newRow += "##L" + bLink.caption;
tmp.erase(0, idx3 + 2);
if(tmp != "")
{
- newRow += "##>";
+ newRow += "##P";
}
idx1 = tmp.find("@@");
}
@@ -145,7 +141,7 @@ void BrowserBox::addRow(const std::string &row)
if (mMode == AUTO_WRAP)
{
- unsigned int j, y = 0;
+ unsigned int y = 0;
unsigned int nextChar;
const char *hyphen = "~";
int hyphenWidth = font->getWidth(hyphen);
@@ -154,7 +150,7 @@ void BrowserBox::addRow(const std::string &row)
for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
{
std::string row = *i;
- for (j = 0; j < row.size(); j++)
+ for (unsigned int j = 0; j < row.size(); j++)
{
std::string character = row.substr(j, 1);
x += font->getWidth(character);
@@ -259,8 +255,7 @@ BrowserBox::draw(gcn::Graphics *graphics)
if ((mHighMode & UNDERLINE))
{
- bool valid;
- graphics->setColor(gcn::Color(textColour->getColour('<', valid)));
+ graphics->setColor(gcn::Color(LINK));
graphics->drawLine(
mLinks[mSelectedLink].x1,
mLinks[mSelectedLink].y2,
@@ -269,10 +264,9 @@ BrowserBox::draw(gcn::Graphics *graphics)
}
}
- unsigned int j;
int x = 0, y = 0;
int wrappedLines = 0;
- gcn::Font *font = getFont();
+ gcn::contrib::SDLTrueTypeFont *font = static_cast<gcn::contrib::SDLTrueTypeFont*>(getFont());
graphics->setColor(BLACK);
for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
@@ -280,103 +274,148 @@ BrowserBox::draw(gcn::Graphics *graphics)
int selColor = BLACK;
int prevColor = selColor;
std::string row = *(i);
+ bool wrapped = false;
x = 0;
- for (j = 0; j < row.size(); j++)
+ // Check for separator lines
+ if (row.find("---", 0) == 0)
+ {
+ for (x = 0; x < getWidth(); x++)
+ {
+ font->drawString(graphics, "-", x, y);
+ x += font->getWidth("-") - 2;
+ }
+ y += font->getHeight();
+ continue;
+ }
+
+ // TODO: Check if we must take texture size limits into account here
+ // TODO: Check if some of the O(n) calls can be removed
+ for (std::string::size_type start = 0, end = std::string::npos;
+ start != std::string::npos;
+ start = end, end = std::string::npos)
{
- if ( (mUseLinksAndUserColors && (j + 3) <= row.size()) ||
- (!mUseLinksAndUserColors && (j == 0)) )
+ // Wrapped line continuation shall be indented
+ if (wrapped)
+ {
+ y += font->getHeight();
+ x = 15;
+ }
+
+ // "Tokenize" the string at control sequences
+ if (mUseLinksAndUserColors)
+ end = row.find("##", start + 1);
+
+ if (mUseLinksAndUserColors ||
+ (!mUseLinksAndUserColors && (start == 0)))
{
- // Check for color change in format "##x"
- if ((row.at(j) == '#') && (row.at(j + 1) == '#'))
+ // Check for color change in format "##x", x = [L,P,0..9]
+ if (row.find("##", start) == start && row.size() > start + 2)
{
- char c = row.at(j + 2);
- if (c == '>')
+ switch (row.at(start + 2))
{
- selColor = prevColor;
- }
- else
- {
- bool valid;
- int rgb = textColour->getColour(c, valid);
- if (c == '<')
- {
+ case 'L': // Link color
prevColor = selColor;
- }
- if (valid)
- {
- selColor = rgb;
- }
- }
- j += 3;
-
- if (j == row.size())
- {
- break;
+ selColor = LINK;
+ break;
+ case 'P': // Previous color
+ selColor = prevColor;
+ break;
+ case '1':
+ prevColor = selColor;
+ selColor = RED;
+ break;
+ case '2':
+ prevColor = selColor;
+ selColor = GREEN;
+ break;
+ case '3':
+ prevColor = selColor;
+ selColor = BLUE;
+ break;
+ case '4':
+ prevColor = selColor;
+ selColor = ORANGE;
+ break;
+ case '5':
+ prevColor = selColor;
+ selColor = YELLOW;
+ break;
+ case '6':
+ prevColor = selColor;
+ selColor = PINK;
+ break;
+ case '7':
+ prevColor = selColor;
+ selColor = PURPLE;
+ break;
+ case '8':
+ prevColor = selColor;
+ selColor = GRAY;
+ break;
+ case '9':
+ prevColor = selColor;
+ selColor = BROWN;
+ break;
+ case '0':
+ default:
+ prevColor = selColor;
+ selColor = BLACK;
}
+ start += 3;
}
graphics->setColor(gcn::Color(selColor));
}
- // Check for line separators in format "---"
- if (row == "---")
- {
- for (x = 0; x < getWidth(); x++)
- {
- const std::string dash = "-";
- font->drawString(graphics, dash, x, y);
- x += font->getWidth("-") - 2;
- }
- break;
- }
- // Draw each char
- else
+ std::string::size_type len =
+ end == std::string::npos ? end : end - start;
+ std::string part = row.substr(start, len);
+
+ // Auto wrap mode
+ if (mMode == AUTO_WRAP &&
+ (x + font->getWidth(part.c_str()) + 10) > getWidth())
{
- std::string character = row.substr(j, 1);
- font->drawString(graphics, character, x, y);
- x += font->getWidth(character.c_str());
+ bool forced = false;
+ char const *hyphen = "~";
+ int hyphenWidth = font->getWidth(hyphen);
- // Auto wrap mode
- if (mMode == AUTO_WRAP)
+ do
{
- unsigned int nextChar = j + 1;
- const std::string hyphen = "~";
- int hyphenWidth = font->getWidth(hyphen);
+ if (!forced)
+ end = row.rfind(" ", end);
- // Wraping between words (at blank spaces)
- if ((nextChar < row.size()) && (row.at(nextChar) == ' '))
+ // Check if we have to (stupidly) force-wrap
+ if (end == std::string::npos || end <= start)
{
- int nextSpacePos = row.find(" ", (nextChar + 1));
- if (nextSpacePos <= 0)
- {
- nextSpacePos = row.size() - 1;
- }
- int nextWordWidth = font->getWidth(
- row.substr(nextChar,
- (nextSpacePos - nextChar)));
-
- if ((x + nextWordWidth + 10) > getWidth())
- {
- x = 15; // Ident in new line
- y += font->getHeight();
- wrappedLines++;
- j++;
- }
+ forced = true;
+ end = row.size();
+ x += hyphenWidth * 2; // Account for the wrap-notifier
+ continue;
}
- // Wrapping looong lines (brutal force)
- else if ((x + 2 * hyphenWidth) > getWidth())
- {
- font->drawString(graphics, hyphen,
- getWidth() - hyphenWidth, y);
- x = 15; // Ident in new line
- y += font->getHeight();
- wrappedLines++;
- }
+ end--;
+
+ part = row.substr(start, end - start + 1);
+ } while ((x + font->getWidth(part.c_str()) + 10) > getWidth());
+
+ if (forced)
+ {
+ x -= hyphenWidth; // Remove the wrap-notifier accounting
+ font->drawString(graphics, hyphen,
+ getWidth() - hyphenWidth, y);
+ end++; // Skip to the next character
}
+ else
+ end += 2; // Skip to after the space
+
+ wrapped = true;
+ wrappedLines++;
}
+ font->drawString(graphics, part, x, y);
+ x += font->getWidth(part.c_str());
}
y += font->getHeight();
setHeight((mTextRows.size() + wrappedLines) * font->getHeight());
}
}
+