Merge branch 'bug_486_add_service_event_progress_to_servicelist'
[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 #include <lib/driver/rc.h>
6
7 eInput::eInput(eWidget *parent): eWidget(parent)
8 {
9         m_mode = 1;
10         m_have_focus = 0;
11 }
12
13 eInput::~eInput()
14 {
15         mayKillFocus();
16 }
17
18 void eInput::setOverwriteMode(int m)
19 {
20         int om = m_mode;
21         m_mode = m;
22         if (om != m_mode)
23                 invalidate();
24 }
25
26 void eInput::setContent(eInputContent *content)
27 {
28         if (m_content)
29                 m_content->setInput(0);
30         m_content = content;
31         if (m_content)
32                 m_content->setInput(this);
33 }
34
35 int eInput::event(int event, void *data, void *data2)
36 {
37         switch (event)
38         {
39         case evtPaint:
40         {
41                 gPainter &painter = *(gPainter*)data2;
42                 ePtr<eWindowStyle> style;
43                 
44                 getStyle(style);
45                 
46                 eWidget::event(event, data, data2);
47                 
48                 ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height()));
49                 
50                 std::string text;
51                 int cursor = -1;
52                 
53                 if (m_content)
54                         m_content->getDisplay(text, cursor);
55                 
56                 eDebug("cursor is %d", cursor);
57                 para->setFont(m_font);
58                 para->renderString(text.empty()?0:text.c_str(), 0);
59                 int glyphs = para->size();
60                 
61                 if (m_have_focus)
62                 {
63                         if (m_mode && cursor < glyphs)
64                         {
65                                         /* in overwrite mode, when not at end of line, invert the current cursor position. */
66                                 para->setGlyphFlag(cursor, GS_INVERT);
67                                 eRect bbox = para->getGlyphBBox(cursor);
68                                 bbox = eRect(bbox.left(), 0, bbox.width(), size().height());
69                                 painter.fill(bbox);
70                         } else
71                         {
72                                         /* otherwise, insert small cursor */
73                                 eRect bbox;
74                                 if (cursor < glyphs)
75                                 {
76                                         bbox = para->getGlyphBBox(cursor);
77                                         bbox = eRect(bbox.left()-1, 0, 2, size().height());
78                                 } else if (cursor)
79                                 {
80                                         bbox = para->getGlyphBBox(cursor - 1);
81                                         bbox = eRect(bbox.right(), 0, 2, size().height());
82                                 } else
83                                 {
84                                         bbox = eRect(0, 0, 2, size().height());
85                                 }
86                                 painter.fill(bbox);
87                         }
88                 }
89                 
90                 painter.renderPara(para, ePoint(0, 0));
91                 
92                 return 0;
93         }
94         case evtAction:
95                 if (isVisible())
96                 {
97                         if ((long)data == ASCII_ACTIONS)
98                         {
99                                 if ((long)data2 == gotAsciiCode)
100                                 {
101                                         if (m_content)
102                                         {
103                                                 extern int getPrevAsciiCode();  // defined in enigma.cpp
104                                                 return m_content->haveKey(getPrevAsciiCode(), m_mode);
105                                         }
106                                 }
107                         }
108                         else if ((long)data == INPUT_ACTIONS)
109                         {
110                                 switch((long)data2)
111                                 {
112                                 case moveLeft:
113                                         if (m_content)
114                                                 m_content->moveCursor(eInputContent::dirLeft);
115                                         break;
116                                 case moveRight:
117                                         if (m_content)
118                                                 m_content->moveCursor(eInputContent::dirRight);
119                                         break;
120                                 case moveHome:
121                                         if (m_content)
122                                                 m_content->moveCursor(eInputContent::dirHome);
123                                         break;
124                                 case moveEnd:
125                                         if (m_content)
126                                                 m_content->moveCursor(eInputContent::dirEnd);
127                                         break;
128                                 case deleteForward:
129                                         if (m_content)
130                                                 m_content->deleteChar(eInputContent::deleteForward);
131                                         break;
132                                 case deleteBackward:
133                                         if (m_content)
134                                                 m_content->deleteChar(eInputContent::deleteBackward);
135                                         break;
136                                 case toggleOverwrite:
137                                         setOverwriteMode(!m_mode);
138                                         break;
139                                 case accept:
140                                         changed();
141                                         mayKillFocus();
142                                 }
143                                 return 1;
144                         }
145                 }
146                 return 0;
147         case evtKey:
148         {
149                 long key = (long)data;
150                 long flags = (long)data2;
151                 if (m_content && !(flags & 1)) // only make/repeat, no break
152                         return m_content->haveKey(key, m_mode);
153                 break;
154         }
155         case evtFocusGot:
156         {
157                 eDebug("focus got in %p", this);
158                 ePtr<eActionMap> ptr;
159                 eActionMap::getInstance(ptr);
160                 ptr->bindAction("InputActions", 0, INPUT_ACTIONS, this);
161                 ptr->bindAction("AsciiActions", 0, ASCII_ACTIONS, this);
162                 m_have_focus = 1;
163                 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii);
164                         // fixme. we should use a style for this.
165                 setBackgroundColor(gRGB(64, 64, 128));
166                 invalidate();
167                 break;
168         }
169         case evtFocusLost:
170         {
171                 eDebug("focus lostin %p", this);
172                 ePtr<eActionMap> ptr;
173                 eActionMap::getInstance(ptr);
174                 ptr->unbindAction(this, INPUT_ACTIONS);
175                 ptr->unbindAction(this, ASCII_ACTIONS);
176                 m_have_focus = 0;
177                 if (m_content)
178                         m_content->validate();
179                 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmNone);
180                 clearBackgroundColor();
181                 invalidate();
182                 break;
183         }
184         default:
185                 break;
186         }
187         return eWidget::event(event, data, data2);
188 }
189
190 void eInput::setFont(gFont *fnt)
191 {
192         m_font = fnt;
193         invalidate();
194 }
195
196 void eInputContent::setInput(eInput *widget)
197 {
198         m_input = widget;
199 }
200