- create DCs for buffered mode
[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, 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                         switch((int)data2)
98                         {
99                         case moveLeft:
100                                 m_content->moveCursor(eInputContent::dirLeft);
101                                 break;
102                         case moveRight:
103                                 m_content->moveCursor(eInputContent::dirRight);
104                                 break;
105                         case moveHome:
106                                 m_content->moveCursor(eInputContent::dirHome);
107                                 break;
108                         case moveEnd:
109                                 m_content->moveCursor(eInputContent::dirEnd);
110                                 break;
111                         case deleteForward:
112                                 m_content->deleteChar(eInputContent::deleteForward);
113                                 break;
114                         case deleteBackward:
115                                 m_content->deleteChar(eInputContent::deleteBackward);
116                                 break;
117                         case toggleOverwrite:
118                                 setOverwriteMode(!m_mode);
119                                 break;
120                         case accept:
121                                 changed();
122                                 mayKillFocus();
123                         }
124                         return 1;
125                 }
126                 return 0;
127         case evtKey:
128         {
129                 int key = (int)data;
130                 int flags = (int)data2;
131                 if (m_content && !(flags & 1)) // only make/repeat, no break
132                         return m_content->haveKey(key, m_mode);
133                 break;
134         }
135         case evtFocusGot:
136         {
137                 eDebug("focus got in %p", this);
138                 ePtr<eActionMap> ptr;
139                 eActionMap::getInstance(ptr);
140                 ptr->bindAction("InputActions", 0, 0, this);
141                         // bind all keys
142                 ptr->bindAction("", 0, 1, this);
143                 m_have_focus = 1;
144                 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii);
145                         // fixme. we should use a style for this.
146                 setBackgroundColor(gRGB(64, 64, 128));
147                 invalidate();
148                 break;
149         }
150         case evtFocusLost:
151         {
152                 eDebug("focus lostin %p", this);
153                 ePtr<eActionMap> ptr;
154                 eActionMap::getInstance(ptr);
155                 ptr->unbindAction(this, 0);
156                 ptr->unbindAction(this, 1);
157                 m_have_focus = 0;
158                 if (m_content)
159                         m_content->validate();
160                 eRCInput::getInstance()->setKeyboardMode(eRCInput::kmNone);
161                 clearBackgroundColor();
162                 invalidate();
163                 break;
164         }
165         default:
166                 break;
167         }
168         return eWidget::event(event, data, data2);
169 }
170
171 void eInput::setFont(gFont *fnt)
172 {
173         m_font = fnt;
174         invalidate();
175 }
176
177 void eInputContent::setInput(eInput *widget)
178 {
179         m_input = widget;
180 }
181