- work on timers
[enigma2.git] / lib / gui / einput.cpp
1 #include <lib/gui/einput.h>
2 #include <lib/gdi/font.h>
3 #include <lib/actions/action.h>
4
5 eInput::eInput(eWidget *parent): eLabel(parent)
6 {
7                 /* default to center alignment */
8         m_valign = alignCenter;
9         m_halign = alignCenter;
10
11         ePtr<eActionMap> ptr;
12         eActionMap::getInstance(ptr);
13         ptr->bindAction("InputActions", 0, 0, this);
14 }
15
16 eInput::~eInput()
17 {
18         ePtr<eActionMap> ptr;
19         eActionMap::getInstance(ptr);
20         ptr->unbindAction(this, 0);
21 }
22
23 void eInput::setContent(eInputContent *content)
24 {
25         if (m_content)
26                 m_content->setInput(0);
27         m_content = content;
28         if (m_content)
29                 m_content->setInput(this);
30 }
31
32 int eInput::event(int event, void *data, void *data2)
33 {
34         switch (event)
35         {
36         case evtPaint:
37         {
38                 gPainter &painter = *(gPainter*)data2;
39                 ePtr<eWindowStyle> style;
40                 
41                 getStyle(style);
42                 
43                 eWidget::event(event, data, data2);
44                 
45                 ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height()));
46                 
47                 std::string text;
48                 int cursor = -1;
49                 
50                 if (m_content)
51                         m_content->getDisplay(text, cursor);
52                 
53                 eDebug("cursor is %d", cursor);
54                 para->setFont(m_font);
55                 para->renderString(text, 0);
56                 
57                 int glyphs = para->size();
58                 eRect bbox;
59                 if (cursor < glyphs)
60                 {
61                         bbox = para->getGlyphBBox(cursor);
62                         bbox = eRect(bbox.left()-1, 0, 2, size().height());
63                 } else
64                 {
65                         bbox = para->getGlyphBBox(cursor - 1);
66                         bbox = eRect(bbox.right(), 0, 2, size().height());
67                 }
68                 painter.fill(bbox);
69                 
70                 painter.renderPara(para, ePoint(0, 0));
71                 
72                 return 0;
73         }
74         case evtAction:
75                 if (isVisible())
76                 {
77                         switch((int)data2)
78                         {
79                         case moveLeft:
80                                 m_content->moveCursor(eInputContent::dirLeft);
81                                 break;
82                         case moveRight:
83                                 m_content->moveCursor(eInputContent::dirRight);
84                                 break;
85                         case moveHome:
86                                 m_content->moveCursor(eInputContent::dirHome);
87                                 break;
88                         case moveEnd:
89                                 m_content->moveCursor(eInputContent::dirEnd);
90                                 break;
91                         case deleteChar:
92                                 // not yet
93                                 break;
94                         }
95                         return 1;
96                 }
97                 return 0;
98         default:
99                 break;
100         }
101         return eLabel::event(event, data, data2);
102 }
103
104 int eInput::getNumber()
105 {
106         return atoi(m_text.c_str());
107 }
108
109 DEFINE_REF(eInputContentNumber);
110
111 void eInputContent::setInput(eInput *widget)
112 {
113         m_input = widget;
114 }
115
116 eInputContentNumber::eInputContentNumber(int cur, int min, int max)
117 {
118         m_min = min;
119         m_max = max;
120         m_value = cur;
121         m_cursor = 0;
122         m_input = 0;
123         recalcLen();
124 }
125
126 void eInputContentNumber::getDisplay(std::string &res, int &cursor)
127 {
128         // TODO
129         char r[128];
130         sprintf(r, "%d", m_value);
131         res = r;
132         cursor = m_cursor;
133 }
134
135 void eInputContentNumber::moveCursor(int dir)
136 {
137         eDebug("move cursor..");
138         int old_cursor = m_cursor;
139         
140         switch (dir)
141         {
142         case dirLeft:
143                 --m_cursor;
144                 break;
145         case dirRight:
146                 ++m_cursor;
147                 break;
148         case dirHome:
149                 m_cursor = 0;
150                 break;
151         case dirEnd:
152                 m_cursor = m_len;
153                 break;
154         }
155         
156         if (m_cursor < 0)
157                 m_cursor = 0;
158         if (m_cursor > m_len)
159                 m_cursor = m_len;
160         
161         if (m_cursor != old_cursor)
162                 if (m_input)
163                         m_input->invalidate();
164 }
165
166 int eInputContentNumber::haveKey(int code)
167 {
168         insertDigit(m_cursor, code);
169         recalcLen();
170         return 0;
171 }
172
173 int eInputContentNumber::isValid()
174 {
175         return m_value >= m_min && m_value <= m_max;
176 }
177
178 void eInputContentNumber::recalcLen()
179 {
180         int v = m_value;
181         m_len = 0;
182         while (v)
183         {
184                 ++m_len;
185                 v /= 10;
186         }
187         
188         if (!m_len) /* zero */
189                 m_len = 1;
190 }
191
192 void eInputContentNumber::insertDigit(int pos, int dig)
193 {
194                 /* get stuff left from cursor */
195         int exp = 1;
196         int i;
197         for (i = 0; i < (m_len - pos - 1); ++i)
198                 exp *= 10;
199         
200                 /* now it's 1...max */
201         int left = m_value / exp;
202         int right = m_value % exp;
203         left *= 10;
204         left += dig;
205         left *= exp;
206         left += right;
207         m_value = left;
208 }