Mana
Loading...
Searching...
No Matches
textbox.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gui/widgets/textbox.h"
23
24#include "gui/gui.h"
25#include "resources/theme.h"
26
27#include <guichan/font.hpp>
28
29#include <sstream>
30
32{
33 auto &palette = gui->getTheme()->getPalette(0);
35 mOutlineColor = palette.getOutlineColor(Theme::TEXT);
36
37 setOpaque(false);
38 setFrameSize(0);
39 mMinWidth = getWidth();
40}
41
42void TextBox::setTextWrapped(const std::string &text, int minDimension)
43{
44 // Make sure parent scroll area sets width of this widget
45 if (getParent())
46 getParent()->logic();
47
48 // Take the supplied minimum dimension as a starting point and try to beat it
49 mMinWidth = minDimension;
50
51 std::stringstream wrappedStream;
52 std::string::size_type spacePos, newlinePos, lastNewlinePos = 0;
53 int minWidth = 0;
54 int xpos;
55
56 spacePos = text.rfind(" ", text.size());
57
58 if (spacePos != std::string::npos)
59 {
60 const std::string word = text.substr(spacePos + 1);
61 const int length = getFont()->getWidth(word);
62
63 if (length > mMinWidth)
64 mMinWidth = length;
65 }
66
67 do
68 {
69 // Determine next piece of string to wrap
70 newlinePos = text.find("\n", lastNewlinePos);
71
72 if (newlinePos == std::string::npos)
73 newlinePos = text.size();
74
75 std::string line =
76 text.substr(lastNewlinePos, newlinePos - lastNewlinePos);
77 std::string::size_type lastSpacePos = 0;
78 xpos = 0;
79
80 do
81 {
82 spacePos = line.find(" ", lastSpacePos);
83
84 if (spacePos == std::string::npos)
85 spacePos = line.size();
86
87 std::string word =
88 line.substr(lastSpacePos, spacePos - lastSpacePos);
89
90 int width = getFont()->getWidth(word);
91
92 if (xpos == 0 && width > mMinWidth)
93 {
94 mMinWidth = width;
95 xpos = width;
96 wrappedStream << word;
97 }
98 else if (xpos != 0 && xpos + getFont()->getWidth(" ") + width <=
100 {
101 xpos += getFont()->getWidth(" ") + width;
102 wrappedStream << " " << word;
103 }
104 else if (lastSpacePos == 0)
105 {
106 xpos += width;
107 wrappedStream << word;
108 }
109 else
110 {
111 if (xpos > minWidth)
112 minWidth = xpos;
113
114 // The window wasn't big enough. Resize it and try again.
115 if (minWidth > mMinWidth)
116 {
117 mMinWidth = minWidth;
118 wrappedStream.clear();
119 wrappedStream.str(std::string());
120 spacePos = 0;
121 lastNewlinePos = 0;
122 newlinePos = text.find("\n", lastNewlinePos);
123 if (newlinePos == std::string::npos)
124 newlinePos = text.size();
125 line = text.substr(lastNewlinePos, newlinePos -
126 lastNewlinePos);
127 width = 0;
128 break;
129 }
130 else
131 {
132 wrappedStream << "\n" << word;
133 }
134 xpos = width;
135 }
136 lastSpacePos = spacePos + 1;
137 }
138 while (spacePos != line.size());
139
140 if (text.find("\n", lastNewlinePos) != std::string::npos)
141 wrappedStream << "\n";
142
143 lastNewlinePos = newlinePos + 1;
144 }
145 while (newlinePos != text.size());
146
147 if (xpos > minWidth)
148 minWidth = xpos;
149
150 mMinWidth = minWidth;
151
152 gcn::TextBox::setText(wrappedStream.str());
153}
154
158void TextBox::draw(gcn::Graphics *graphics)
159{
160 unsigned int i;
161
162 if (mOpaque)
163 {
164 graphics->setColor(getBackgroundColor());
165 graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight()));
166 }
167
168 if (isFocused() && isEditable())
169 {
170 drawCaret(graphics,
171 getFont()->getWidth(mTextRows[mCaretRow].substr(0, mCaretColumn)),
172 mCaretRow * getFont()->getHeight());
173 }
174
176 graphics->setFont(getFont());
177
178 auto g = static_cast<Graphics*>(graphics);
179
180 for (i = 0; i < mTextRows.size(); i++)
181 {
182 // Move the text one pixel so we can have a caret before a letter.
183 g->drawText(mTextRows[i],
184 1,
185 i * getFont()->getHeight(),
186 gcn::Graphics::LEFT,
187 *mTextColor,
188 getFont(),
189 mOutlineColor.has_value(),
190 false,
192 }
193}
A central point of control for graphics.
Definition graphics.h:78
void drawText(const std::string &text, int x, int y, gcn::Graphics::Alignment alignment, const gcn::Color &color, gcn::Font *font, bool outline=false, bool shadow=false, const std::optional< gcn::Color > &outlineColor={}, const std::optional< gcn::Color > &shadowColor={})
Definition graphics.cpp:176
void setColor(const gcn::Color &color) override
Definition graphics.h:255
Theme * getTheme() const
The global GUI theme.
Definition gui.h:138
const gcn::Color & getColor(int type) const
Gets the color associated with the type.
Definition palette.h:72
int mMinWidth
Definition textbox.h:62
TextBox()
Definition textbox.cpp:31
std::optional< gcn::Color > mOutlineColor
Definition textbox.h:64
void draw(gcn::Graphics *graphics) override
Draws the text.
Definition textbox.cpp:158
void setTextWrapped(const std::string &text, int minDimension)
Sets the text after wrapping it to the current width of the widget.
Definition textbox.cpp:42
const gcn::Color * mTextColor
Definition textbox.h:63
const Palette & getPalette(size_t index) const
Definition theme.cpp:328
@ TEXT
Definition theme.h:214
Graphics * graphics
Definition client.cpp:104
Gui * gui
The GUI system.
Definition gui.cpp:50