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