]> Dogcows Code - chaz/openbox/blob - otk/label.cc
initialize _font
[chaz/openbox] / otk / label.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #include "config.h"
4
5 #include "label.hh"
6 #include "display.hh"
7 #include "rendercontrol.hh"
8
9 #include <string>
10
11 namespace otk {
12
13 Label::Label(Widget *parent)
14 : Widget(parent),
15 _text(""),
16 _font(0),
17 _justify_horz(RenderStyle::LeftTopJustify),
18 _justify_vert(RenderStyle::LeftTopJustify),
19 _highlight(false)
20 {
21 styleChanged(*RenderStyle::style(screen()));
22 }
23
24 Label::~Label()
25 {
26 }
27
28 void Label::setHorizontalJustify(RenderStyle::Justify j)
29 {
30 _justify_horz = j;
31 refresh();
32 }
33
34 void Label::setVerticalJustify(RenderStyle::Justify j)
35 {
36 _justify_vert = j;
37 refresh();
38 }
39
40 void Label::setHighlighted(bool h)
41 {
42 _highlight = h;
43 styleChanged(*RenderStyle::style(screen()));
44 refresh();
45 }
46
47 void Label::setText(const ustring &text)
48 {
49 bool utf = text.utf8();
50 std::string s = text.c_str(); // use a normal string, for its functionality
51
52 _parsedtext.clear();
53 _text = text;
54
55 // parse it into multiple lines
56 std::string::size_type p = 0;
57 while (p != std::string::npos) {
58 std::string::size_type p2 = s.find('\n', p);
59 std::string s(s.substr(p, (p2==std::string::npos?p2:p2-p)));
60
61 // turn tabs into spaces (multiples of 8)
62 std::string::size_type t;
63 while ((t = s.find('\t')) != std::string::npos)
64 s.replace(t, 1, std::string(8 - t % 8, ' '));
65
66 _parsedtext.push_back(s);
67 _parsedtext.back().setUtf8(utf);
68 p = (p2==std::string::npos?p2:p2+1);
69 }
70 calcDefaultSizes();
71 }
72
73 void Label::setFont(const Font *f)
74 {
75 _font = f;
76 calcDefaultSizes();
77 }
78
79 void Label::calcDefaultSizes()
80 {
81 int longest = 0;
82 // find the longest line
83 std::vector<ustring>::iterator it, end = _parsedtext.end();
84 for (it = _parsedtext.begin(); it != end; ++it) {
85 int length = _font->measureString(*it);
86 if (length < 0) continue; // lines too long get skipped
87 if (length > longest) longest = length;
88 }
89 setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4,
90 _parsedtext.size() * _font->height() + borderWidth() * 2 +
91 bevel() * 2));
92 }
93
94 void Label::styleChanged(const RenderStyle &style)
95 {
96 if (_highlight) {
97 _texture = style.labelFocusBackground();
98 _forecolor = style.textFocusColor();
99 } else {
100 _texture = style.labelUnfocusBackground();
101 _forecolor = style.textUnfocusColor();
102 }
103 if (_font != style.labelFont()) {
104 _font = style.labelFont();
105 calcDefaultSizes();
106 }
107 }
108
109 void Label::renderForeground(Surface &surface)
110 {
111 const RenderControl *control = display->renderControl(screen());
112 int sidemargin = bevel() * 2;
113 int y = bevel();
114 int w = area().width() - borderWidth() * 2 - sidemargin * 2;
115 int h = area().height() - borderWidth() * 2 - bevel() * 2;
116
117 switch (_justify_vert) {
118 case RenderStyle::RightBottomJustify:
119 y += h - (_parsedtext.size() * _font->height());
120 if (y < bevel()) y = bevel();
121 break;
122 case RenderStyle::CenterJustify:
123 y += (h - (_parsedtext.size() * _font->height())) / 2;
124 if (y < bevel()) y = bevel();
125 break;
126 case RenderStyle::LeftTopJustify:
127 break;
128 }
129
130 if (w <= 0) return; // can't fit anything
131
132 std::vector<ustring>::iterator it, end = _parsedtext.end();
133 for (it = _parsedtext.begin(); it != end; ++it, y += _font->height()) {
134 ustring t = *it; // the actual text to draw
135 int x = sidemargin; // x coord for the text
136
137 // find a string that will fit inside the area for text
138 ustring::size_type text_len = t.size();
139 int length;
140
141 do {
142 t.resize(text_len);
143 length = _font->measureString(t);
144 } while (length > w && text_len-- > 0);
145 if (length < 0) continue; // lines too long get skipped
146
147 if (text_len <= 0) continue; // won't fit anything
148
149 // justify the text
150 switch (_justify_horz) {
151 case RenderStyle::RightBottomJustify:
152 x += w - length;
153 break;
154 case RenderStyle::CenterJustify:
155 x += (w - length) / 2;
156 break;
157 case RenderStyle::LeftTopJustify:
158 break;
159 }
160
161 control->drawString(surface, *_font, x, y, *_forecolor, t);
162 }
163 }
164
165 }
This page took 0.047337 seconds and 5 git commands to generate.