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