implement borders for ePixmap widgets (add feature #589)
[enigma2.git] / lib / gui / elabel.cpp
1 #include <lib/gui/elabel.h>
2 #include <lib/gdi/font.h>
3
4 eLabel::eLabel(eWidget *parent, int markedPos): eWidget(parent)
5 {
6         m_pos = markedPos;
7         ePtr<eWindowStyle> style;
8         getStyle(style);
9         
10         style->getFont(eWindowStyle::fontStatic, m_font);
11         
12                 /* default to topleft alignment */
13         m_valign = alignTop;
14         m_halign = alignLeft;
15         
16         m_have_foreground_color = 0;
17         m_have_shadow_color = 0;
18         
19         m_nowrap = 0;
20 }
21
22 int eLabel::event(int event, void *data, void *data2)
23 {
24         switch (event)
25         {
26         case evtPaint:
27         {
28                 ePtr<eWindowStyle> style;
29                 
30                 getStyle(style);
31                 
32                 eWidget::event(event, data, data2);
33
34                 gPainter &painter = *(gPainter*)data2;
35                 
36                 if (m_pos != -1)
37                 {
38                         style->setStyle(painter, eWindowStyle::styleLabel);
39                         ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height()));
40                         para->setFont(m_font);
41                         para->renderString(m_text.empty()?0:m_text.c_str(), 0);
42
43                         if (m_halign == alignLeft)
44                                 para->realign(eTextPara::dirLeft);
45                         else if (m_halign == alignCenter)
46                                 para->realign(eTextPara::dirCenter);
47                         else if (m_halign == alignRight)
48                                 para->realign(eTextPara::dirRight);
49                         else if (m_halign == alignBlock)
50                                 para->realign(eTextPara::dirBlock);
51
52                         int glyphs = para->size();
53
54                         if (m_pos == -2) {  /* All glyphs inverted */
55                                 eRect bbox;
56                                 int left = 0, right = 0;
57                                 for (int i=0; i<glyphs; i++)
58                                         para->setGlyphFlag(i, GS_INVERT);
59                                 if (glyphs > 0) {
60                                         bbox = para->getGlyphBBox(0);
61                                         left = bbox.left();
62                                         bbox = para->getGlyphBBox(glyphs-1);
63                                         right = bbox.left() + bbox.width();
64                                 }
65                                 bbox = eRect(left, 0, right-left, size().height());
66                                 painter.fill(bbox);
67                         } else if ((m_pos < 0) || (m_pos >= glyphs))
68                                 eWarning("glyph index %d in eLabel out of bounds!", m_pos);
69                         else
70                         {
71                                 para->setGlyphFlag(m_pos, GS_INVERT);
72                                 eRect bbox;
73                                 bbox = para->getGlyphBBox(m_pos);
74                                 bbox = eRect(bbox.left(), 0, bbox.width(), size().height());
75                                 painter.fill(bbox);
76                         }
77
78                         painter.renderPara(para, ePoint(0, 0));
79                         return 0;
80                 } else
81                 {
82                         painter.setFont(m_font);
83                         style->setStyle(painter, eWindowStyle::styleLabel);
84                         
85                         if (m_have_shadow_color)
86                                 painter.setForegroundColor(m_shadow_color);
87                         else if (m_have_foreground_color)
88                                 painter.setForegroundColor(m_foreground_color);
89                         
90                         int flags = 0;
91                         if (m_valign == alignTop)
92                                 flags |= gPainter::RT_VALIGN_TOP;
93                         else if (m_valign == alignCenter)
94                                 flags |= gPainter::RT_VALIGN_CENTER;
95                         else if (m_valign == alignBottom)
96                                 flags |= gPainter::RT_VALIGN_BOTTOM;
97         
98                         if (m_halign == alignLeft)
99                                 flags |= gPainter::RT_HALIGN_LEFT;
100                         else if (m_halign == alignCenter)
101                                 flags |= gPainter::RT_HALIGN_CENTER;
102                         else if (m_halign == alignRight)
103                                 flags |= gPainter::RT_HALIGN_RIGHT;
104                         else if (m_halign == alignBlock)
105                                 flags |= gPainter::RT_HALIGN_BLOCK;
106                         
107                         if (!m_nowrap)
108                                 flags |= gPainter::RT_WRAP;
109                         
110                                 /* if we don't have shadow, m_shadow_offset will be 0,0 */
111                         painter.renderText(eRect(-m_shadow_offset.x(), -m_shadow_offset.y(), size().width(), size().height()), m_text, flags);
112                         
113                         if (m_have_shadow_color)
114                         {
115                                 if (!m_have_foreground_color)
116                                         style->setStyle(painter, eWindowStyle::styleLabel);
117                                 else
118                                         painter.setForegroundColor(m_foreground_color);
119                                 painter.setBackgroundColor(m_shadow_color);
120                                 painter.renderText(eRect(0, 0, size().width(), size().height()), m_text, flags);
121                         }
122                         
123                         return 0;
124                 }
125         }
126         case evtChangedFont:
127         case evtChangedText:
128         case evtChangedAlignment:
129         case evtChangedMarkedPos:
130                 invalidate();
131                 return 0;
132         default:
133                 return eWidget::event(event, data, data2);
134         }
135 }
136
137 void eLabel::setText(const std::string &string)
138 {
139         if (m_text == string)
140                 return;
141         m_text = string;
142         event(evtChangedText);
143 }
144
145 void eLabel::setMarkedPos(int markedPos)
146 {
147         m_pos = markedPos;
148         event(evtChangedMarkedPos);
149 }
150
151 void eLabel::setFont(gFont *font)
152 {
153         m_font = font;
154         event(evtChangedFont);
155 }
156
157 gFont* eLabel::getFont()
158 {
159         return m_font;
160 }
161
162 void eLabel::setVAlign(int align)
163 {
164         m_valign = align;
165         event(evtChangedAlignment);
166 }
167
168 void eLabel::setHAlign(int align)
169 {
170         m_halign = align;
171         event(evtChangedAlignment);
172 }
173
174 void eLabel::setForegroundColor(const gRGB &col)
175 {
176         if ((!m_have_foreground_color) || !(m_foreground_color == col))
177         {
178                 m_foreground_color = col;
179                 m_have_foreground_color = 1;
180                 invalidate();
181         }
182 }
183
184 void eLabel::setShadowColor(const gRGB &col)
185 {
186         if ((!m_have_shadow_color) || !(m_shadow_color == col))
187         {
188                 m_shadow_color = col;
189                 m_have_shadow_color = 1;
190                 invalidate();
191         }
192 }
193
194 void eLabel::setShadowOffset(const ePoint &offset)
195 {
196         m_shadow_offset = offset;
197 }
198
199 void eLabel::setNoWrap(int nowrap)
200 {
201         if (m_nowrap != nowrap)
202         {
203                 m_nowrap = nowrap;
204                 invalidate();
205         }
206 }
207
208 void eLabel::clearForegroundColor()
209 {
210         if (m_have_foreground_color)
211         {
212                 m_have_foreground_color = 0;
213                 invalidate();
214         }
215 }
216
217 eSize eLabel::calculateSize()
218 {
219         ePtr<eTextPara> p = new eTextPara(eRect(0, 0, size().width(), size().height()));
220         
221         p->setFont(m_font);
222         p->renderString(m_text.empty()?0:m_text.c_str(), m_nowrap ? 0 : RS_WRAP);
223         
224         eRect bbox = p->getBoundBox();
225         return bbox.size();
226 }