]> icculus.org git repositories - dana/openbox.git/blob - otk/label.cc
Brand spankin new widgets for otk (Label and Button).
[dana/openbox.git] / 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 {
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::setText(const ustring &text)
41 {
42   bool utf = text.utf8();
43   std::string s = text.c_str(); // use a normal string, for its functionality
44
45   _parsedtext.clear();
46   
47   // parse it into multiple lines
48   std::string::size_type p = 0;
49   while (p != std::string::npos) {
50     std::string::size_type p2 = s.find('\n', p);
51     _parsedtext.push_back(s.substr(p, (p2==std::string::npos?p2:p2-p)));
52     _parsedtext.back().setUtf8(utf);
53     p = (p2==std::string::npos?p2:p2+1);
54   }
55   calcDefaultSizes();
56 }
57
58 void Label::setFont(const Font *f)
59 {
60   _font = f;
61   calcDefaultSizes();
62 }
63
64 void Label::calcDefaultSizes()
65 {
66   unsigned int longest = 0;
67   // find the longest line
68   std::vector<ustring>::iterator it, end = _parsedtext.end();
69   for (it = _parsedtext.begin(); it != end; ++it) {
70     unsigned int length = _font->measureString(*it);
71     if (length > longest) longest = length;
72   }
73   setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4,
74                   _parsedtext.size() * _font->height() + borderWidth() * 2 +
75                   bevel() * 2));
76 }
77   
78 void Label::styleChanged(const RenderStyle &style)
79 {
80   _texture = style.labelFocusBackground();
81   _forecolor = style.textFocusColor();
82   _font = style.labelFont();
83   Widget::styleChanged(style);
84   calcDefaultSizes();
85 }
86
87 void Label::renderForeground(Surface &surface)
88 {
89   const RenderControl *control = display->renderControl(screen());
90   unsigned int sidemargin = bevel() * 2;
91   int y = bevel();
92   unsigned int w = area().width() - borderWidth() * 2 - sidemargin * 2;
93   unsigned int h = area().height() - borderWidth() * 2 - bevel() * 2;
94
95   switch (_justify_vert) {
96   case RenderStyle::RightBottomJustify:
97     y += h - (_parsedtext.size() * _font->height());
98     if (y < bevel()) y = bevel();
99     break;
100   case RenderStyle::CenterJustify:
101     y += (h - (_parsedtext.size() * _font->height())) / 2;
102     if (y < bevel()) y = bevel();
103     break;
104   case RenderStyle::LeftTopJustify:
105     break;
106   }
107   
108   if (w <= 0) return; // can't fit anything
109   
110   std::vector<ustring>::iterator it, end = _parsedtext.end();
111   for (it = _parsedtext.begin(); it != end; ++it, y += _font->height()) {
112     ustring t = *it; // the actual text to draw
113     int x = sidemargin;    // x coord for the text
114
115     // find a string that will fit inside the area for text
116     ustring::size_type text_len = t.size();
117     unsigned int length;
118       
119     do {
120       t.resize(text_len);
121       length = _font->measureString(t);
122     } while (length > w && text_len-- > 0);
123
124     if (text_len <= 0) continue; // won't fit anything
125
126     // justify the text
127     switch (_justify_horz) {
128     case RenderStyle::RightBottomJustify:
129       x += w - length;
130       break;
131     case RenderStyle::CenterJustify:
132       x += (w - length) / 2;
133       break;
134     case RenderStyle::LeftTopJustify:
135       break;
136     }
137  
138     control->drawString(surface, *_font, x, y, *_forecolor, t);
139  }
140 }
141
142 }