#include <lib/gui/einput.h>
#include <lib/gdi/font.h>
#include <lib/actions/action.h>
-#include <linux/input.h>
-eInput::eInput(eWidget *parent): eLabel(parent)
-{
- /* default to center alignment */
- m_valign = alignCenter;
- m_halign = alignCenter;
+#include <lib/driver/rc.h>
- ePtr<eActionMap> ptr;
- eActionMap::getInstance(ptr);
- ptr->bindAction("InputActions", 0, 0, this);
-
- // bind all keys
- ptr->bindAction("", 0, 1, this);
+eInput::eInput(eWidget *parent): eWidget(parent)
+{
+ m_mode = 1;
+ m_have_focus = 0;
}
eInput::~eInput()
{
- ePtr<eActionMap> ptr;
- eActionMap::getInstance(ptr);
- ptr->unbindAction(this, 0);
- ptr->unbindAction(this, 1);
+ mayKillFocus();
+}
+
+void eInput::setOverwriteMode(int m)
+{
+ int om = m_mode;
+ m_mode = m;
+ if (om != m_mode)
+ invalidate();
}
void eInput::setContent(eInputContent *content)
eDebug("cursor is %d", cursor);
para->setFont(m_font);
- para->renderString(text, 0);
-
+ para->renderString(text.empty()?0:text.c_str(), 0);
int glyphs = para->size();
- eRect bbox;
- if (cursor < glyphs)
- {
- bbox = para->getGlyphBBox(cursor);
- bbox = eRect(bbox.left()-1, 0, 2, size().height());
- } else
+
+ if (m_have_focus)
{
- bbox = para->getGlyphBBox(cursor - 1);
- bbox = eRect(bbox.right(), 0, 2, size().height());
+ if (m_mode && cursor < glyphs)
+ {
+ /* in overwrite mode, when not at end of line, invert the current cursor position. */
+ para->setGlyphFlag(cursor, GS_INVERT);
+ eRect bbox = para->getGlyphBBox(cursor);
+ bbox = eRect(bbox.left(), 0, bbox.width(), size().height());
+ painter.fill(bbox);
+ } else
+ {
+ /* otherwise, insert small cursor */
+ eRect bbox;
+ if (cursor < glyphs)
+ {
+ bbox = para->getGlyphBBox(cursor);
+ bbox = eRect(bbox.left()-1, 0, 2, size().height());
+ } else if (cursor)
+ {
+ bbox = para->getGlyphBBox(cursor - 1);
+ bbox = eRect(bbox.right(), 0, 2, size().height());
+ } else
+ {
+ bbox = eRect(0, 0, 2, size().height());
+ }
+ painter.fill(bbox);
+ }
}
- painter.fill(bbox);
painter.renderPara(para, ePoint(0, 0));
case evtAction:
if (isVisible())
{
- switch((int)data2)
+ if ((long)data == ASCII_ACTIONS)
+ {
+ if ((long)data2 == gotAsciiCode)
+ {
+ if (m_content)
+ {
+ extern int getPrevAsciiCode(); // defined in enigma.cpp
+ return m_content->haveKey(getPrevAsciiCode(), m_mode);
+ }
+ }
+ }
+ else if ((long)data == INPUT_ACTIONS)
{
- case moveLeft:
- m_content->moveCursor(eInputContent::dirLeft);
- break;
- case moveRight:
- m_content->moveCursor(eInputContent::dirRight);
- break;
- case moveHome:
- m_content->moveCursor(eInputContent::dirHome);
- break;
- case moveEnd:
- m_content->moveCursor(eInputContent::dirEnd);
- break;
- case deleteForward:
- m_content->deleteChar(eInputContent::deleteForward);
- break;
- case deleteBackward:
- m_content->deleteChar(eInputContent::deleteBackward);
- break;
+ switch((long)data2)
+ {
+ case moveLeft:
+ if (m_content)
+ m_content->moveCursor(eInputContent::dirLeft);
+ break;
+ case moveRight:
+ if (m_content)
+ m_content->moveCursor(eInputContent::dirRight);
+ break;
+ case moveHome:
+ if (m_content)
+ m_content->moveCursor(eInputContent::dirHome);
+ break;
+ case moveEnd:
+ if (m_content)
+ m_content->moveCursor(eInputContent::dirEnd);
+ break;
+ case deleteForward:
+ if (m_content)
+ m_content->deleteChar(eInputContent::deleteForward);
+ break;
+ case deleteBackward:
+ if (m_content)
+ m_content->deleteChar(eInputContent::deleteBackward);
+ break;
+ case toggleOverwrite:
+ setOverwriteMode(!m_mode);
+ break;
+ case accept:
+ changed();
+ mayKillFocus();
+ }
+ return 1;
}
- return 1;
}
return 0;
case evtKey:
{
- int key = (int)data;
- int flags = (int)data2;
- if (m_content && !(flags & 1))
- m_content->haveKey(key);
- break;
- }
- default:
+ long key = (long)data;
+ long flags = (long)data2;
+ if (m_content && !(flags & 1)) // only make/repeat, no break
+ return m_content->haveKey(key, m_mode);
break;
}
- return eLabel::event(event, data, data2);
-}
-
-int eInput::getNumber()
-{
- return atoi(m_text.c_str());
-}
-
-DEFINE_REF(eInputContentNumber);
-
-void eInputContent::setInput(eInput *widget)
-{
- m_input = widget;
-}
-
-eInputContentNumber::eInputContentNumber(int cur, int min, int max)
-{
- m_min = min;
- m_max = max;
- m_value = cur;
- m_cursor = 0;
- m_input = 0;
- recalcLen();
-}
-
-void eInputContentNumber::getDisplay(std::string &res, int &cursor)
-{
- // TODO
- char r[128];
- sprintf(r, "%d", m_value);
- res = r;
- cursor = m_cursor;
-}
-
-void eInputContentNumber::moveCursor(int dir)
-{
- eDebug("move cursor..");
- int old_cursor = m_cursor;
-
- switch (dir)
+ case evtFocusGot:
{
- case dirLeft:
- --m_cursor;
- break;
- case dirRight:
- ++m_cursor;
+ eDebug("focus got in %p", this);
+ ePtr<eActionMap> ptr;
+ eActionMap::getInstance(ptr);
+ ptr->bindAction("InputActions", 0, INPUT_ACTIONS, this);
+ ptr->bindAction("AsciiActions", 0, ASCII_ACTIONS, this);
+ m_have_focus = 1;
+ eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii);
+ // fixme. we should use a style for this.
+ setBackgroundColor(gRGB(64, 64, 128));
+ invalidate();
break;
- case dirHome:
- m_cursor = 0;
- break;
- case dirEnd:
- m_cursor = m_len;
- break;
- }
-
- if (m_cursor < 0)
- m_cursor = 0;
- if (m_cursor > m_len)
- m_cursor = m_len;
-
- if (m_cursor != old_cursor)
- if (m_input)
- m_input->invalidate();
-}
-
-int eInputContentNumber::haveKey(int code)
-{
- int have_digit = -1;
-
-#define ASCII(x) (x | 0x8000)
-#define DIGIT(x) case KEY_##x: case KEY_KP##x: case ASCII(x|0x30): have_digit=x; break;
- switch (code)
- {
- DIGIT(0);
- DIGIT(1);
- DIGIT(2);
- DIGIT(3);
- DIGIT(4);
- DIGIT(5);
- DIGIT(6);
- DIGIT(7);
- DIGIT(8);
- DIGIT(9);
}
-
- if (have_digit != -1)
+ case evtFocusLost:
{
- insertDigit(m_cursor, have_digit);
- m_cursor++;
-
- recalcLen();
-
- // can happen when 0 -> x
- if (m_cursor > m_len)
- m_cursor = m_len;
-
- if (m_input)
- m_input->invalidate();
+ eDebug("focus lostin %p", this);
+ ePtr<eActionMap> ptr;
+ eActionMap::getInstance(ptr);
+ ptr->unbindAction(this, INPUT_ACTIONS);
+ ptr->unbindAction(this, ASCII_ACTIONS);
+ m_have_focus = 0;
+ if (m_content)
+ m_content->validate();
+ eRCInput::getInstance()->setKeyboardMode(eRCInput::kmNone);
+ clearBackgroundColor();
+ invalidate();
+ break;
}
- return 0;
-}
-
-void eInputContentNumber::deleteChar(int dir)
-{
- if (dir == deleteForward)
- {
- eDebug("forward");
- if (m_cursor != m_len)
- ++m_cursor;
- else
- return;
+ default:
+ break;
}
- /* backward delete at begin */
- if (!m_cursor)
- return;
- insertDigit(m_cursor, -1);
-
- if (m_len > 1)
- m_cursor--;
- recalcLen();
- if (m_input)
- m_input->invalidate();
+ return eWidget::event(event, data, data2);
}
-int eInputContentNumber::isValid()
+void eInput::setFont(gFont *fnt)
{
- return m_value >= m_min && m_value <= m_max;
+ m_font = fnt;
+ invalidate();
}
-void eInputContentNumber::recalcLen()
+void eInputContent::setInput(eInput *widget)
{
- int v = m_value;
- m_len = 0;
- while (v)
- {
- ++m_len;
- v /= 10;
- }
-
- if (!m_len) /* zero */
- m_len = 1;
+ m_input = widget;
}
-void eInputContentNumber::insertDigit(int pos, int dig)
-{
- /* get stuff left from cursor */
- int exp = 1;
- int i;
- for (i = 0; i < (m_len - pos); ++i)
- exp *= 10;
-
- /* now it's 1...max */
- int left = m_value / exp;
- int right = m_value % exp;
-
- if (dig >= 0)
- {
- left *= 10;
- left += dig;
- } else if (dig == -1) /* delete */
- {
- left /= 10;
- }
-
- left *= exp;
- left += right;
- m_value = left;
-}