diff options
author | Björn Steinbrink <B.Steinbrink@gmx.de> | 2007-09-21 03:58:07 +0000 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2009-01-05 20:21:28 -0700 |
commit | 77db175ceabe8d05665191835d0250a927d93d32 (patch) | |
tree | 1dc69120e9455c30bc2ec36b2aa9bb63ae2f1295 /src | |
parent | fde40d91bceb1c7e7818d898f8731089ff87a9f4 (diff) | |
download | mana-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')
-rw-r--r-- | src/gui/browserbox.cpp | 215 | ||||
-rw-r--r-- | src/gui/browserbox.h | 30 |
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 + |