summaryrefslogtreecommitdiff
path: root/src/gui/widgets/browserbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets/browserbox.cpp')
-rw-r--r--src/gui/widgets/browserbox.cpp138
1 files changed, 40 insertions, 98 deletions
diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp
index bc424962..7b5d40bb 100644
--- a/src/gui/widgets/browserbox.cpp
+++ b/src/gui/widgets/browserbox.cpp
@@ -164,61 +164,8 @@ void BrowserBox::addRow(const std::string &row)
setWidth(w);
}
- // TODO: Optimize! There's no point in wrapping all text rows again, just
- // do the one that was just added (but take into account discarded rows?).
- if (mMode == AUTO_WRAP)
- {
- unsigned int wrapCount = 0;
- unsigned int nextChar;
- const char *tilde = "~";
- int tildeWidth = font->getWidth(tilde);
- int x = 0;
-
- for (auto row : mTextRows)
- {
- for (unsigned int j = 0; j < row.size(); ++j)
- {
- std::string character = row.substr(j, 1);
- x += font->getWidth(character);
- nextChar = j + 1;
-
- // Wraping between words (at blank spaces)
- if (nextChar < row.size() && row.at(nextChar) == ' ')
- {
- int nextSpacePos = static_cast<int>(
- row.find(" ", (nextChar + 1)));
- if (nextSpacePos <= 0)
- nextSpacePos = static_cast<int>(row.size()) - 1;
-
- int nextWordWidth = font->getWidth(
- row.substr(nextChar,
- (nextSpacePos - nextChar)));
-
- if (x + nextWordWidth + 10 > getWidth())
- {
- x = 15; // Indent in new line
- ++wrapCount;
- ++j;
- }
- }
- // Wrapping looong lines (brutal force)
- else if (x + 2 * tildeWidth > getWidth())
- {
- x = 15; // Ident in new line
- ++wrapCount;
- }
- }
- }
-
- setHeight(lineHeight * (mTextRows.size() + wrapCount - 1)
- + fontHeight);
- }
- else
- {
- setHeight(lineHeight * (mTextRows.size() - 1) + fontHeight);
- }
mUpdateTime = 0;
- updateHeight();
+ maybeRelayoutText();
}
void BrowserBox::clearRows()
@@ -228,7 +175,7 @@ void BrowserBox::clearRows()
setWidth(0);
setHeight(0);
mSelectedLink = -1;
- updateHeight();
+ maybeRelayoutText();
}
struct MouseOverLink
@@ -269,14 +216,14 @@ void BrowserBox::mouseMoved(gcn::MouseEvent &event)
void BrowserBox::draw(gcn::Graphics *graphics)
{
- gcn::ClipRectangle cr = graphics->getCurrentClipArea();
+ const gcn::ClipRectangle &cr = graphics->getCurrentClipArea();
mYStart = cr.y - cr.yOffset;
int yEnd = mYStart + cr.height;
if (mYStart < 0)
mYStart = 0;
- if (getWidth() != mWidth)
- updateHeight();
+ if (getWidth() != mLastLayoutWidth)
+ maybeRelayoutText();
if (mOpaque)
{
@@ -308,11 +255,11 @@ void BrowserBox::draw(gcn::Graphics *graphics)
}
}
- for (auto &part : mLineParts)
+ for (const auto &part : mLineParts)
{
- if (part.getY() + 50 < mYStart)
+ if (part.y + 50 < mYStart)
continue;
- if (part.getY() > yEnd)
+ if (part.y > yEnd)
break;
// Use the correct font
@@ -322,69 +269,64 @@ void BrowserBox::draw(gcn::Graphics *graphics)
if (mShadows)
{
graphics->setColor(Theme::getThemeColor(Theme::SHADOW,
- part.getColor().a / 2));
+ part.color.a / 2));
+
if (mOutline)
- {
- graphics->drawText(part.getText(), part.getX() + 2,
- part.getY() + 2);
- }
+ graphics->drawText(part.text, part.x + 2, part.y + 2);
else
- {
- graphics->drawText(part.getText(), part.getX() + 1,
- part.getY() + 1);
- }
+ graphics->drawText(part.text, part.x + 1, part.y + 1);
}
if (mOutline)
{
// Text outline
graphics->setColor(Theme::getThemeColor(Theme::OUTLINE,
- part.getColor().a / 4));
- graphics->drawText(part.getText(), part.getX() + 1, part.getY());
- graphics->drawText(part.getText(), part.getX() - 1, part.getY());
- graphics->drawText(part.getText(), part.getX(), part.getY() + 1);
- graphics->drawText(part.getText(), part.getX(), part.getY() - 1);
+ part.color.a / 4));
+ graphics->drawText(part.text, part.x + 1, part.y);
+ graphics->drawText(part.text, part.x - 1, part.y);
+ graphics->drawText(part.text, part.x, part.y + 1);
+ graphics->drawText(part.text, part.x, part.y - 1);
}
// the main text
- graphics->setColor(part.getColor());
- graphics->drawText(part.getText(), part.getX(), part.getY());
+ graphics->setColor(part.color);
+ graphics->drawText(part.text, part.x, part.y);
}
-
- return;
}
-int BrowserBox::calcHeight()
+/**
+ * Relayouts all text rows.
+ */
+void BrowserBox::relayoutText()
{
- int x = 0, y = 0;
- int wrappedLines = 0;
+ int y = 0;
unsigned link = 0;
- gcn::Font *font = getFont();
+ const gcn::Font *font = getFont();
const int fontHeight = font->getHeight();
const int minusWidth = font->getWidth("-");
const int tildeWidth = font->getWidth("~");
int lineHeight = fontHeight;
- if (auto *ttf = dynamic_cast<TrueTypeFont*>(font))
- lineHeight = ttf->getLineHeight();
+ if (auto *trueTypeFont = dynamic_cast<const TrueTypeFont*>(font))
+ lineHeight = trueTypeFont->getLineHeight();
gcn::Color selColor = Theme::getThemeColor(Theme::TEXT);
const gcn::Color &textColor = Theme::getThemeColor(Theme::TEXT);
mLineParts.clear();
- for (auto row : mTextRows)
+ for (const auto &row : mTextRows)
{
bool wrapped = false;
- x = 0;
+ int x = 0;
// Check for separator lines
if (row.find("---", 0) == 0)
{
for (x = 0; x < getWidth(); x++)
{
- mLineParts.push_back(LinePart(x, y, selColor, "-"));
+ mLineParts.push_back(LinePart { x, y, selColor, "-" });
x += minusWidth - 2;
}
@@ -438,7 +380,6 @@ int BrowserBox::calcHeight()
}
else
{
-
switch (c)
{
case '1': selColor = RED; break;
@@ -456,6 +397,7 @@ int BrowserBox::calcHeight()
}
}
+ // Update the position of the links
if (c == '<' && link < mLinks.size())
{
const int size =
@@ -520,8 +462,8 @@ int BrowserBox::calcHeight()
if (forced)
{
x -= tildeWidth; // Remove the wrap-notifier accounting
- mLineParts.push_back(LinePart(getWidth() - tildeWidth,
- y, selColor, "~"));
+ mLineParts.push_back(LinePart { getWidth() - tildeWidth,
+ y, selColor, "~" });
end++; // Skip to the next character
}
else
@@ -530,10 +472,9 @@ int BrowserBox::calcHeight()
}
wrapped = true;
- wrappedLines++;
}
- mLineParts.push_back(LinePart(x, y, selColor, part));
+ mLineParts.push_back(LinePart { x, y, selColor, part });
const int partWidth = font->getWidth(part);
if (mMode == AUTO_WRAP && partWidth == 0)
@@ -541,19 +482,20 @@ int BrowserBox::calcHeight()
x += partWidth;
}
+
y += lineHeight;
}
- return (mTextRows.size() + wrappedLines - 1) * lineHeight + fontHeight;
+
+ mLastLayoutWidth = getWidth();
+ setHeight(y);
}
-void BrowserBox::updateHeight()
+void BrowserBox::maybeRelayoutText()
{
if (mAlwaysUpdate || !mUpdateTime || std::abs(mUpdateTime - tick_time) > 10
|| mTextRows.size() < 3)
{
- mWidth = getWidth();
- mHeight = calcHeight();
- setHeight(mHeight);
+ relayoutText();
mUpdateTime = tick_time;
}
}