1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
7 #include "rendercontrol.hh"
13 Label::Label(int screen, EventDispatcher *ed, int bevel)
14 : Widget(screen, ed, Widget::Horizontal, bevel, true),
17 _justify_horz(RenderStyle::LeftTopJustify),
18 _justify_vert(RenderStyle::LeftTopJustify),
21 styleChanged(*RenderStyle::style(screen));
24 Label::Label(Widget *parent)
28 _justify_horz(RenderStyle::LeftTopJustify),
29 _justify_vert(RenderStyle::LeftTopJustify),
32 styleChanged(*RenderStyle::style(screen()));
39 void Label::setHorizontalJustify(RenderStyle::Justify j)
45 void Label::setVerticalJustify(RenderStyle::Justify j)
51 void Label::setHighlighted(bool h)
54 styleChanged(*RenderStyle::style(screen()));
58 void Label::setText(const ustring &text)
60 bool utf = text.utf8();
61 std::string s = text.c_str(); // use a normal string, for its functionality
66 // parse it into multiple lines
67 std::string::size_type p = 0;
68 while (p != std::string::npos) {
69 std::string::size_type p2 = s.find('\n', p);
70 std::string s(s.substr(p, (p2==std::string::npos?p2:p2-p)));
72 // turn tabs into spaces (multiples of 8)
73 std::string::size_type t;
74 while ((t = s.find('\t')) != std::string::npos)
75 s.replace(t, 1, std::string(8 - t % 8, ' '));
77 _parsedtext.push_back(s);
78 _parsedtext.back().setUtf8(utf);
79 p = (p2==std::string::npos?p2:p2+1);
84 void Label::setFont(const Font *f)
90 void Label::calcDefaultSizes()
93 // find the longest line
94 std::vector<ustring>::iterator it, end = _parsedtext.end();
95 for (it = _parsedtext.begin(); it != end; ++it) {
96 int length = _font->measureString(*it);
97 if (length < 0) continue; // lines too long get skipped
98 if (length > longest) longest = length;
100 setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4,
101 _parsedtext.size() * _font->height() + borderWidth() * 2 +
105 void Label::styleChanged(const RenderStyle &style)
108 _texture = style.labelFocusBackground();
109 _forecolor = style.textFocusColor();
111 _texture = style.labelUnfocusBackground();
112 _forecolor = style.textUnfocusColor();
114 if (_font != style.labelFont()) {
115 _font = style.labelFont();
120 void Label::renderForeground(Surface &surface)
122 const RenderControl *control = display->renderControl(screen());
123 int sidemargin = bevel() * 2;
125 int w = area().width() - borderWidth() * 2 - sidemargin * 2;
126 int h = area().height() - borderWidth() * 2 - bevel() * 2;
128 switch (_justify_vert) {
129 case RenderStyle::RightBottomJustify:
130 y += h - (_parsedtext.size() * _font->height());
131 if (y < bevel()) y = bevel();
133 case RenderStyle::CenterJustify:
134 y += (h - (_parsedtext.size() * _font->height())) / 2;
135 if (y < bevel()) y = bevel();
137 case RenderStyle::LeftTopJustify:
141 if (w <= 0) return; // can't fit anything
143 std::vector<ustring>::iterator it, end = _parsedtext.end();
144 for (it = _parsedtext.begin(); it != end; ++it, y += _font->height()) {
145 ustring t = *it; // the actual text to draw
146 int x = sidemargin; // x coord for the text
148 // find a string that will fit inside the area for text
149 ustring::size_type text_len = t.size();
154 length = _font->measureString(t);
155 } while (length > w && text_len-- > 0);
156 if (length < 0) continue; // lines too long get skipped
158 if (text_len <= 0) continue; // won't fit anything
161 switch (_justify_horz) {
162 case RenderStyle::RightBottomJustify:
165 case RenderStyle::CenterJustify:
166 x += (w - length) / 2;
168 case RenderStyle::LeftTopJustify:
172 control->drawString(surface, *_font, x, y, *_forecolor, t);