summaryrefslogtreecommitdiff
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
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
-rw-r--r--src/gui/browserbox.cpp215
-rw-r--r--src/gui/browserbox.h30
2 files changed, 151 insertions, 94 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());
}
}
+
diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h
index 1c1e283a..7f871c96 100644
--- a/src/gui/browserbox.h
+++ b/src/gui/browserbox.h
@@ -25,8 +25,8 @@
#include <iosfwd>
#include <vector>
-#include <guichan/mouselistener.hpp>
#include <guichan/widget.hpp>
+#include <guichan/mouselistener.hpp>
#include "../guichanfwd.h"
#include "../main.h"
@@ -111,13 +111,30 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener
};
/**
- * Some colours used in the browser box
+ * BrowserBox colors.
+ *
+ * NOTES (by Javila):
+ * - color values is "0x" prefix followed by HTML color style.
+ * - we can add up to 10 different colors: [0..9].
+ * - we need a link and a highlighted link colors.
+ * - not all colors will be fine with all backgrounds due transparent
+ * windows and widgets. So, I think it's better keep BrowserBox
+ * opaque (white background) by default.
*/
-
enum {
- BLACK = 0x000000,
- BGCOLOR = 0xffffff,
- HIGHLIGHT = 0xcacaca
+ BLACK = 0x000000, /**< Color 0 */
+ RED = 0xff0000, /**< Color 1 */
+ GREEN = 0x1fa052, /**< Color 2 */
+ BLUE = 0x0000ff, /**< Color 3 */
+ ORANGE = 0xe0980e, /**< Color 4 */
+ YELLOW = 0xf1dc27, /**< Color 5 */
+ PINK = 0xff00d8, /**< Color 6 */
+ PURPLE = 0x8415e2, /**< Color 7 */
+ GRAY = 0x919191, /**< Color 8 */
+ BROWN = 0x8e4c17, /**< Color 9 */
+ BGCOLOR = 0xffffff, /**< Bg color for opacity */
+ LINK = 0xe50d0d, /**< Color L */
+ HIGHLIGHT = 0xcacaca /**< Bg color for highlighted link */
};
/**
@@ -148,3 +165,4 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener
};
#endif
+