Merge branch 'bug_538_ignore_global_actions_in_standby'
[enigma2.git] / lib / gui / einputnumber.cpp
1 #include <lib/gui/einputnumber.h>
2 #include <linux/input.h>
3
4 DEFINE_REF(eInputContentNumber);
5
6 eInputContentNumber::eInputContentNumber(int cur, int min, int max)
7 {
8         m_min = min;
9         m_max = max;
10         m_value = cur;
11         m_cursor = 0;
12         m_input = 0;
13         recalcLen();
14 }
15
16 void eInputContentNumber::getDisplay(std::string &res, int &cursor)
17 {
18         // TODO
19         char r[128];
20         
21         int e = 1;
22         for (int i = 1; i < m_len; ++i)
23                 e *= 10;
24
25         int v = m_value;
26         
27         int i;
28         for (i = 0; i < m_len; ++i)
29         {
30                 int rem = v / e;
31                 r[i] = '0' + rem;
32                 v %= e;
33                 
34                 e /= 10;
35         }
36         
37         r[i] = 0;
38         
39         res = r;
40         cursor = m_cursor;
41 }
42
43 void eInputContentNumber::moveCursor(int dir)
44 {
45         eDebug("move cursor..");
46         int old_cursor = m_cursor;
47         
48         switch (dir)
49         {
50         case dirLeft:
51                 --m_cursor;
52                 break;
53         case dirRight:
54                 ++m_cursor;
55                 break;
56         case dirHome:
57                 m_cursor = 0;
58                 break;
59         case dirEnd:
60                 m_cursor = m_len;
61                 break;
62         }
63         
64         if (m_cursor < 0)
65                 m_cursor = 0;
66         if (m_cursor > m_len)
67                 m_cursor = m_len;
68         
69         if (m_cursor != old_cursor)
70                 if (m_input)
71                         m_input->invalidate();
72 }
73
74 int eInputContentNumber::haveKey(int code, int overwrite)
75 {
76         int have_digit = -1;
77
78                 /* we handle KEY_KPx, but not KEY_x. otherwise we would get stuff twice. */
79 #define ASCII(x) (x | 0x8000)
80 #define DIGIT(x) /* case KEY_##x: */ case KEY_KP##x: case ASCII(x|0x30): have_digit=x; break;
81         switch (code)
82         {
83         DIGIT(0);
84         DIGIT(1);
85         DIGIT(2);
86         DIGIT(3);
87         DIGIT(4);
88         DIGIT(5);
89         DIGIT(6);
90         DIGIT(7);
91         DIGIT(8);
92         DIGIT(9);
93         default:
94                 return 0;
95         }
96         
97         if (have_digit != -1)
98         {
99                 insertDigit(m_cursor, have_digit);
100                         /* if overwrite and not end of line, erase char first. */
101                 if (overwrite && m_cursor < m_len)
102                         insertDigit(m_cursor + 1, -1);
103                 else
104                         ++m_len;
105                 
106                 m_cursor++;
107                 
108                 ASSERT(m_cursor <= m_len);
109  
110                 if (m_input)
111                         m_input->invalidate();
112                 return 1;
113         }
114         return 0;
115 }
116
117 void eInputContentNumber::deleteChar(int dir)
118 {
119         if (dir == deleteForward)
120         {
121                 eDebug("forward");
122                 if (m_cursor != m_len)
123                         ++m_cursor;
124                 else
125                         return;
126         }
127                 /* backward delete at begin */
128         if (!m_cursor)
129                 return;
130         
131         if (!m_len)
132                 return;
133         
134         insertDigit(m_cursor, -1);
135         
136         m_len--;
137         m_cursor--;
138
139         if (m_input)
140                 m_input->invalidate();
141 }
142
143 int eInputContentNumber::isValid()
144 {
145         return m_value >= m_min && m_value <= m_max;
146 }
147
148 void eInputContentNumber::validate()
149 {
150         recalcLen();
151 }
152
153 void eInputContentNumber::setValue(int val)
154 {
155         m_value = val;
156         recalcLen();
157         if (m_cursor > m_len)
158                 m_cursor = m_len;
159         if (m_input)
160                 m_input->invalidate();
161 }
162
163 int eInputContentNumber::getValue()
164 {
165         return m_value;
166 }
167
168 void eInputContentNumber::recalcLen()
169 {
170         int v = m_value;
171         m_len = 0;
172         while (v)
173         {
174                 ++m_len;
175                 v /= 10;
176         }
177         
178         if (!m_len) /* zero */
179                 m_len = 1;
180 }
181
182 void eInputContentNumber::insertDigit(int pos, int dig)
183 {
184                 /* get stuff left from cursor */
185         int exp = 1;
186         int i;
187         for (i = 0; i < (m_len - pos); ++i)
188                 exp *= 10;
189         
190                 /* now it's 1...max */
191         int left = m_value / exp;
192         int right = m_value % exp;
193         
194         if (dig >= 0)
195         {
196                 left *= 10;
197                 left += dig;
198         } else if (dig == -1) /* delete */
199         {
200                 left /= 10;
201         }
202         
203         left *= exp;
204         left += right;
205         m_value = left;
206 }
207