1 #include <lib/gui/elistbox.h>
2 #include <lib/gui/elistboxcontent.h>
6 The basic idea is to have an interface which gives all relevant list
7 processing functions, and can be used by the listbox to browse trough
10 The listbox directly uses the implemented cursor. It tries hard to avoid
11 iterating trough the (possibly very large) list, so it should be O(1),
12 i.e. the performance should not be influenced by the size of the list.
14 The list interface knows how to draw the current entry to a specified
15 offset. Different interfaces can be used to adapt different lists,
16 pre-filter lists on the fly etc.
18 cursorSave/Restore is used to avoid re-iterating the list on redraw.
19 The current selection is always selected as cursor position, the
20 cursor is then positioned to the start, and then iterated. This gives
21 at most 2x m_items_per_page cursor movements per redraw, indepenent
22 of the size of the list.
24 Although cursorSet is provided, it should be only used when there is no
25 other way, as it involves iterating trough the list.
28 iListboxContent::~iListboxContent()
32 void iListboxContent::setListbox(eListbox *lb)
37 DEFINE_REF(eListboxTestContent);
39 void eListboxTestContent::cursorHome()
44 void eListboxTestContent::cursorEnd()
49 int eListboxTestContent::cursorMove(int count)
55 else if (m_cursor > size())
60 int eListboxTestContent::cursorValid()
62 return m_cursor < size();
65 int eListboxTestContent::cursorSet(int n)
71 else if (m_cursor > size())
76 int eListboxTestContent::cursorGet()
81 void eListboxTestContent::cursorSave()
83 m_saved_cursor = m_cursor;
86 void eListboxTestContent::cursorRestore()
88 m_cursor = m_saved_cursor;
91 int eListboxTestContent::size()
96 RESULT eListboxTestContent::connectItemChanged(const Slot0<void> &itemChanged, ePtr<eConnection> &connection)
101 void eListboxTestContent::setSize(const eSize &size)
106 void eListboxTestContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
108 ePtr<gFont> fnt = new gFont("Arial", 14);
109 painter.clip(eRect(offset, m_size));
110 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
115 painter.setFont(fnt);
117 sprintf(string, "%d.)", m_cursor);
119 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
121 painter.renderText(eRect(text_offset, m_size), string);
124 style.drawFrame(painter, eRect(offset, m_size), eWindowStyle::frameListboxEntry);
130 //////////////////////////////////////
132 DEFINE_REF(eListboxStringContent);
134 eListboxStringContent::eListboxStringContent()
140 void eListboxStringContent::cursorHome()
142 m_cursor = m_list.begin();
146 void eListboxStringContent::cursorEnd()
148 m_cursor = m_list.end();
149 m_cursor_number = m_size;
152 int eListboxStringContent::cursorMove(int count)
156 while (count && (m_cursor != m_list.end()))
162 } else if (count < 0)
164 while (count && (m_cursor != m_list.begin()))
175 int eListboxStringContent::cursorValid()
177 return m_cursor != m_list.end();
180 int eListboxStringContent::cursorSet(int n)
188 int eListboxStringContent::cursorGet()
190 return m_cursor_number;
193 void eListboxStringContent::cursorSave()
195 m_saved_cursor = m_cursor;
196 m_saved_cursor_number = m_cursor_number;
199 void eListboxStringContent::cursorRestore()
201 m_cursor = m_saved_cursor;
202 m_cursor_number = m_saved_cursor_number;
205 int eListboxStringContent::size()
210 void eListboxStringContent::setSize(const eSize &size)
215 void eListboxStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
217 ePtr<gFont> fnt = new gFont("Arial", 14);
218 painter.clip(eRect(offset, m_itemsize));
219 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
222 eDebug("item %d", m_cursor_number);
225 eDebug("is valid..");
226 painter.setFont(fnt);
228 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
230 painter.renderText(eRect(text_offset, m_itemsize), *m_cursor);
233 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
239 void eListboxStringContent::setList(std::list<std::string> &list)
242 m_size = list.size();
246 //////////////////////////////////////
248 DEFINE_REF(eListboxPythonStringContent);
250 eListboxPythonStringContent::eListboxPythonStringContent()
255 eListboxPythonStringContent::~eListboxPythonStringContent()
259 void eListboxPythonStringContent::cursorHome()
264 void eListboxPythonStringContent::cursorEnd()
269 int eListboxPythonStringContent::cursorMove(int count)
275 else if (m_cursor > size())
280 int eListboxPythonStringContent::cursorValid()
282 return m_cursor < size();
285 int eListboxPythonStringContent::cursorSet(int n)
291 else if (m_cursor > size())
296 int eListboxPythonStringContent::cursorGet()
301 void eListboxPythonStringContent::cursorSave()
303 m_saved_cursor = m_cursor;
306 void eListboxPythonStringContent::cursorRestore()
308 m_cursor = m_saved_cursor;
311 int eListboxPythonStringContent::size()
315 return PyList_Size(m_list);
318 void eListboxPythonStringContent::setSize(const eSize &size)
323 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
325 ePtr<gFont> fnt = new gFont("Arial", 14);
326 painter.clip(eRect(offset, m_itemsize));
327 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
330 if (m_list && cursorValid())
332 PyObject *item = PyList_GetItem(m_list, m_cursor); // borrowed reference!
333 painter.setFont(fnt);
335 /* the user can supply tuples, in this case the first one will be displayed. */
336 if (PyTuple_Check(item))
337 item = PyTuple_GetItem(item, 0);
339 const char *string = PyString_Check(item) ? PyString_AsString(item) : "<not-a-string>";
341 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
343 painter.renderText(eRect(text_offset, m_itemsize), string);
346 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
352 void eListboxPythonStringContent::setList(PyObject *list)
355 if (!PyList_Check(list))
365 PyObject *eListboxPythonStringContent::getCurrentSelection()
371 PyObject *r = PyList_GetItem(m_list, m_cursor);
376 //////////////////////////////////////