aboutsummaryrefslogtreecommitdiff
path: root/lib/gui
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2005-05-14 15:23:23 +0000
committerFelix Domke <tmbinc@elitedvb.net>2005-05-14 15:23:23 +0000
commit7bc4a59528ab13f3062dc1520e76f9ecedd87400 (patch)
tree9d6e91be12147eee77d82ec5b49c24ae44f85bd3 /lib/gui
parentab8d418f82b2835c267d88ded5d748a6f0e8a852 (diff)
downloadenigma2-7bc4a59528ab13f3062dc1520e76f9ecedd87400.tar.gz
enigma2-7bc4a59528ab13f3062dc1520e76f9ecedd87400.zip
- work on timers
- add eInput widget - add python/Tools - add flexible listbox content
Diffstat (limited to 'lib/gui')
-rw-r--r--lib/gui/Makefile.am3
-rw-r--r--lib/gui/einput.cpp208
-rw-r--r--lib/gui/einput.h80
-rw-r--r--lib/gui/elabel.h2
-rw-r--r--lib/gui/elistbox.cpp12
-rw-r--r--lib/gui/elistbox.h2
-rw-r--r--lib/gui/elistboxcontent.cpp118
-rw-r--r--lib/gui/elistboxcontent.h12
8 files changed, 431 insertions, 6 deletions
diff --git a/lib/gui/Makefile.am b/lib/gui/Makefile.am
index 44f5a16d..24f70676 100644
--- a/lib/gui/Makefile.am
+++ b/lib/gui/Makefile.am
@@ -7,6 +7,7 @@ noinst_LIBRARIES = libenigma_gui.a
libenigma_gui_a_SOURCES = \
ebutton.cpp elabel.cpp eslider.cpp ewidget.cpp ewidgetdesktop.cpp \
ewindow.cpp ewindowstyle.cpp elistbox.cpp elistboxcontent.cpp \
- epixmap.cpp ewindowstyleskinned.cpp
+ epixmap.cpp ewindowstyleskinned.cpp einput.cpp
+
diff --git a/lib/gui/einput.cpp b/lib/gui/einput.cpp
new file mode 100644
index 00000000..b2c8ad14
--- /dev/null
+++ b/lib/gui/einput.cpp
@@ -0,0 +1,208 @@
+#include <lib/gui/einput.h>
+#include <lib/gdi/font.h>
+#include <lib/actions/action.h>
+
+eInput::eInput(eWidget *parent): eLabel(parent)
+{
+ /* default to center alignment */
+ m_valign = alignCenter;
+ m_halign = alignCenter;
+
+ ePtr<eActionMap> ptr;
+ eActionMap::getInstance(ptr);
+ ptr->bindAction("InputActions", 0, 0, this);
+}
+
+eInput::~eInput()
+{
+ ePtr<eActionMap> ptr;
+ eActionMap::getInstance(ptr);
+ ptr->unbindAction(this, 0);
+}
+
+void eInput::setContent(eInputContent *content)
+{
+ if (m_content)
+ m_content->setInput(0);
+ m_content = content;
+ if (m_content)
+ m_content->setInput(this);
+}
+
+int eInput::event(int event, void *data, void *data2)
+{
+ switch (event)
+ {
+ case evtPaint:
+ {
+ gPainter &painter = *(gPainter*)data2;
+ ePtr<eWindowStyle> style;
+
+ getStyle(style);
+
+ eWidget::event(event, data, data2);
+
+ ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height()));
+
+ std::string text;
+ int cursor = -1;
+
+ if (m_content)
+ m_content->getDisplay(text, cursor);
+
+ eDebug("cursor is %d", cursor);
+ para->setFont(m_font);
+ para->renderString(text, 0);
+
+ int glyphs = para->size();
+ eRect bbox;
+ if (cursor < glyphs)
+ {
+ bbox = para->getGlyphBBox(cursor);
+ bbox = eRect(bbox.left()-1, 0, 2, size().height());
+ } else
+ {
+ bbox = para->getGlyphBBox(cursor - 1);
+ bbox = eRect(bbox.right(), 0, 2, size().height());
+ }
+ painter.fill(bbox);
+
+ painter.renderPara(para, ePoint(0, 0));
+
+ return 0;
+ }
+ case evtAction:
+ if (isVisible())
+ {
+ switch((int)data2)
+ {
+ 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 deleteChar:
+ // not yet
+ break;
+ }
+ return 1;
+ }
+ return 0;
+ default:
+ 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 dirLeft:
+ --m_cursor;
+ break;
+ case dirRight:
+ ++m_cursor;
+ 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)
+{
+ insertDigit(m_cursor, code);
+ recalcLen();
+ return 0;
+}
+
+int eInputContentNumber::isValid()
+{
+ return m_value >= m_min && m_value <= m_max;
+}
+
+void eInputContentNumber::recalcLen()
+{
+ int v = m_value;
+ m_len = 0;
+ while (v)
+ {
+ ++m_len;
+ v /= 10;
+ }
+
+ if (!m_len) /* zero */
+ m_len = 1;
+}
+
+void eInputContentNumber::insertDigit(int pos, int dig)
+{
+ /* get stuff left from cursor */
+ int exp = 1;
+ int i;
+ for (i = 0; i < (m_len - pos - 1); ++i)
+ exp *= 10;
+
+ /* now it's 1...max */
+ int left = m_value / exp;
+ int right = m_value % exp;
+ left *= 10;
+ left += dig;
+ left *= exp;
+ left += right;
+ m_value = left;
+}
diff --git a/lib/gui/einput.h b/lib/gui/einput.h
new file mode 100644
index 00000000..b742a6d8
--- /dev/null
+++ b/lib/gui/einput.h
@@ -0,0 +1,80 @@
+#ifndef __lib_gui_einput_h
+#define __lib_gui_einput_h
+
+#include <lib/gui/elabel.h>
+#include <lib/python/connections.h>
+
+class eInputContent;
+
+class eInput: public eLabel
+{
+public:
+ eInput(eWidget *parent);
+ virtual ~eInput();
+ PSignal0<void> changed;
+
+ int m_cursor;
+
+ enum InputActions {
+ moveLeft,
+ moveRight,
+ moveHome,
+ moveEnd,
+ deleteChar
+ };
+
+ void setContent(eInputContent *cnt);
+
+ int getNumber();
+protected:
+ ePtr<eInputContent> m_content;
+ int event(int event, void *data=0, void *data2=0);
+};
+
+class eInputContent: public iObject
+{
+public:
+ /* management stuff */
+ void setInput(eInput *widget);
+ /* display stuff */
+ virtual void getDisplay(std::string &res, int &cursor)=0;
+
+ /* movement / user actions */
+ enum {
+ dirLeft, dirRight,
+ dirHome, dirEnd,
+ /* contents can define their own directions */
+ dirUser
+ };
+ virtual void moveCursor(int dir)=0;
+ /* no movement keys except stuff like '.' or so*/
+ virtual int haveKey(int code)=0;
+
+ virtual int isValid()=0;
+protected:
+ eInput *m_input;
+};
+
+class eInputContentNumber: public eInputContent
+{
+ DECLARE_REF(eInputContentNumber);
+public:
+ eInputContentNumber(int cur, int min, int max);
+
+ void getDisplay(std::string &res, int &cursor);
+ void moveCursor(int dir);
+ int haveKey(int code);
+ int isValid();
+
+private:
+ void recalcLen();
+
+ void insertDigit(int pos, int dig);
+
+ int m_value;
+ int m_cursor, m_len;
+
+ int m_min, m_max;
+};
+
+#endif
diff --git a/lib/gui/elabel.h b/lib/gui/elabel.h
index 7e07f438..c19eb0ac 100644
--- a/lib/gui/elabel.h
+++ b/lib/gui/elabel.h
@@ -25,6 +25,7 @@ public:
protected:
ePtr<gFont> m_font;
int m_valign, m_halign;
+ std::string m_text;
int event(int event, void *data=0, void *data2=0);
private:
enum eLabelEvent
@@ -33,7 +34,6 @@ private:
evtChangedFont,
evtChangedAlignment
};
- std::string m_text;
};
#endif
diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp
index ba2e3522..4598fa09 100644
--- a/lib/gui/elistbox.cpp
+++ b/lib/gui/elistbox.cpp
@@ -9,6 +9,8 @@ eListbox::eListbox(eWidget *parent): eWidget(parent)
ePtr<eActionMap> ptr;
eActionMap::getInstance(ptr);
+ m_itemheight = 20;
+
ptr->bindAction("ListboxActions", 0, 0, this);
}
@@ -146,11 +148,19 @@ int eListbox::event(int event, void *data, void *data2)
void eListbox::recalcSize()
{
- m_itemheight = 20;
m_content->setSize(eSize(size().width(), m_itemheight));
m_items_per_page = size().height() / m_itemheight;
}
+void eListbox::setItemHeight(int h)
+{
+ if (h)
+ m_itemheight = h;
+ else
+ m_itemheight = 20;
+ recalcSize();
+}
+
void eListbox::entryAdded(int index)
{
/* manage our local pointers. when the entry was added before the current position, we have to advance. */
diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h
index 9e23bde3..29349cbb 100644
--- a/lib/gui/elistbox.h
+++ b/lib/gui/elistbox.h
@@ -73,6 +73,8 @@ public:
pageDown,
justCheck
};
+
+ void setItemHeight(int h);
#ifndef SWIG
/* entryAdded: an entry was added *before* the given index. it's index is the given number. */
diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp
index d51729d2..54e3a24d 100644
--- a/lib/gui/elistboxcontent.cpp
+++ b/lib/gui/elistboxcontent.cpp
@@ -377,6 +377,11 @@ PyObject *eListboxPythonStringContent::getCurrentSelection()
return r;
}
+void eListboxPythonStringContent::invalidateEntry(int index)
+{
+ m_listbox->entryChanged(index);
+}
+
//////////////////////////////////////
void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
@@ -424,8 +429,117 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
painter.clippop();
}
-void eListboxPythonConfigContent::invalidateEntry(int index)
+//////////////////////////////////////
+
+void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
{
- m_listbox->entryChanged(index);
+ painter.clip(eRect(offset, m_itemsize));
+ style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
+ painter.clear();
+
+ if (m_list && cursorValid())
+ {
+ PyObject *items = PyList_GetItem(m_list, m_cursor); // borrowed reference!
+
+ if (!items)
+ {
+ eDebug("eListboxPythonMultiContent: error getting item %d", m_cursor);
+ painter.clippop();
+ return;
+ }
+
+ if (!PyList_Check(items))
+ {
+ eDebug("eListboxPythonMultiContent: list entry %d is not a list", m_cursor);
+ painter.clippop();
+ return;
+ }
+
+ int size = PyList_Size(items);
+ for (int i = 0; i < size; ++i)
+ {
+ PyObject *item = PyList_GetItem(items, i); // borrowed reference!
+
+ if (!item)
+ {
+ eDebug("eListboxPythonMultiContent: ?");
+ painter.clippop();
+ return;
+ }
+
+
+ PyObject *px, *py, *pwidth, *pheight, *pfnt, *pstring, *pflags;
+
+ /*
+ we have a list of tuples:
+
+ (x, y, width, height, fnt, flags, "bla" ),
+
+ */
+
+ if (!PyTuple_Check(item))
+ {
+ eDebug("eListboxPythonMultiContent did not receive a tuple.");
+ painter.clippop();
+ return;
+ }
+
+ px = PyTuple_GetItem(item, 0);
+ py = PyTuple_GetItem(item, 1);
+ pwidth = PyTuple_GetItem(item, 2);
+ pheight = PyTuple_GetItem(item, 3);
+ pfnt = PyTuple_GetItem(item, 4);
+ pflags = PyTuple_GetItem(item, 5);
+ pstring = PyTuple_GetItem(item, 6);
+
+ if (!(px && py && pwidth && pheight && pfnt && pstring))
+ {
+ eDebug("eListboxPythonMultiContent received too small tuple (must be (x, y, width, height, fnt, flags, string[, ...])");
+ painter.clippop();
+ return;
+ }
+
+ pstring = PyObject_Str(pstring);
+
+ const char *string = (PyString_Check(pstring)) ? PyString_AsString(pstring) : "<not-a-string>";
+
+ int x = PyInt_AsLong(px);
+ int y = PyInt_AsLong(py);
+ int width = PyInt_AsLong(pwidth);
+ int height = PyInt_AsLong(pheight);
+ int flags = PyInt_AsLong(pflags);
+
+ int fnt = PyInt_AsLong(pfnt);
+
+ if (m_font.find(fnt) == m_font.end())
+ {
+ eDebug("eListboxPythonMultiContent: specified font %d was not found!", fnt);
+ Py_XDECREF(pstring);
+ painter.clippop();
+ return;
+ }
+
+ eRect r = eRect(x, y, width, height);
+ r.moveBy(offset);
+
+ painter.setFont(m_font[fnt]);
+
+ painter.renderText(r, string, flags);
+
+ Py_XDECREF(pstring);
+
+ if (selected)
+ style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
+ }
+ }
+
+ painter.clippop();
}
+void eListboxPythonMultiContent::setFont(int fnt, gFont *font)
+{
+ if (font)
+ m_font[fnt] = font;
+ else
+ m_font.erase(fnt);
+}
diff --git a/lib/gui/elistboxcontent.h b/lib/gui/elistboxcontent.h
index 0c4cb001..6a4cdaaa 100644
--- a/lib/gui/elistboxcontent.h
+++ b/lib/gui/elistboxcontent.h
@@ -103,6 +103,7 @@ protected:
/* the following functions always refer to the selected item */
virtual void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
+ void invalidateEntry(int index);
protected:
PyObject *m_list;
@@ -115,10 +116,19 @@ class eListboxPythonConfigContent: public eListboxPythonStringContent
{
public:
void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
- void invalidateEntry(int index);
void setSeperation(int sep) { m_seperation = sep; }
private:
int m_seperation;
};
+class eListboxPythonMultiContent: public eListboxPythonStringContent
+{
+public:
+ void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
+
+ void setFont(int fnt, gFont *fnt);
+private:
+ std::map<int, ePtr<gFont> > m_font;
+};
+
#endif