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 iListboxContent::iListboxContent(): m_listbox(0)
36 void iListboxContent::setListbox(eListbox *lb)
41 DEFINE_REF(eListboxTestContent);
43 void eListboxTestContent::cursorHome()
48 void eListboxTestContent::cursorEnd()
53 int eListboxTestContent::cursorMove(int count)
59 else if (m_cursor > size())
64 int eListboxTestContent::cursorValid()
66 return m_cursor < size();
69 int eListboxTestContent::cursorSet(int n)
75 else if (m_cursor > size())
80 int eListboxTestContent::cursorGet()
85 void eListboxTestContent::cursorSave()
87 m_saved_cursor = m_cursor;
90 void eListboxTestContent::cursorRestore()
92 m_cursor = m_saved_cursor;
95 int eListboxTestContent::size()
100 RESULT eListboxTestContent::connectItemChanged(const Slot0<void> &itemChanged, ePtr<eConnection> &connection)
105 void eListboxTestContent::setSize(const eSize &size)
110 void eListboxTestContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
112 ePtr<gFont> fnt = new gFont("Arial", 14);
113 painter.clip(eRect(offset, m_size));
114 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
119 painter.setFont(fnt);
121 sprintf(string, "%d.)", m_cursor);
123 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
125 painter.renderText(eRect(text_offset, m_size), string);
128 style.drawFrame(painter, eRect(offset, m_size), eWindowStyle::frameListboxEntry);
134 //////////////////////////////////////
136 DEFINE_REF(eListboxStringContent);
138 eListboxStringContent::eListboxStringContent()
144 void eListboxStringContent::cursorHome()
146 m_cursor = m_list.begin();
150 void eListboxStringContent::cursorEnd()
152 m_cursor = m_list.end();
153 m_cursor_number = m_size;
156 int eListboxStringContent::cursorMove(int count)
160 while (count && (m_cursor != m_list.end()))
166 } else if (count < 0)
168 while (count && (m_cursor != m_list.begin()))
179 int eListboxStringContent::cursorValid()
181 return m_cursor != m_list.end();
184 int eListboxStringContent::cursorSet(int n)
192 int eListboxStringContent::cursorGet()
194 return m_cursor_number;
197 void eListboxStringContent::cursorSave()
199 m_saved_cursor = m_cursor;
200 m_saved_cursor_number = m_cursor_number;
203 void eListboxStringContent::cursorRestore()
205 m_cursor = m_saved_cursor;
206 m_cursor_number = m_saved_cursor_number;
209 int eListboxStringContent::size()
214 void eListboxStringContent::setSize(const eSize &size)
219 void eListboxStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
221 ePtr<gFont> fnt = new gFont("Arial", 14);
222 painter.clip(eRect(offset, m_itemsize));
223 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
226 eDebug("item %d", m_cursor_number);
229 eDebug("is valid..");
230 painter.setFont(fnt);
232 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
234 painter.renderText(eRect(text_offset, m_itemsize), *m_cursor);
237 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
243 void eListboxStringContent::setList(std::list<std::string> &list)
246 m_size = list.size();
250 //////////////////////////////////////
252 DEFINE_REF(eListboxPythonStringContent);
254 eListboxPythonStringContent::eListboxPythonStringContent()
259 eListboxPythonStringContent::~eListboxPythonStringContent()
263 void eListboxPythonStringContent::cursorHome()
268 void eListboxPythonStringContent::cursorEnd()
273 int eListboxPythonStringContent::cursorMove(int count)
279 else if (m_cursor > size())
284 int eListboxPythonStringContent::cursorValid()
286 return m_cursor < size();
289 int eListboxPythonStringContent::cursorSet(int n)
295 else if (m_cursor > size())
300 int eListboxPythonStringContent::cursorGet()
305 void eListboxPythonStringContent::cursorSave()
307 m_saved_cursor = m_cursor;
310 void eListboxPythonStringContent::cursorRestore()
312 m_cursor = m_saved_cursor;
315 int eListboxPythonStringContent::size()
319 return PyList_Size(m_list);
322 void eListboxPythonStringContent::setSize(const eSize &size)
327 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
329 ePtr<gFont> fnt = new gFont("Arial", 14);
330 painter.clip(eRect(offset, m_itemsize));
331 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
334 if (m_list && cursorValid())
336 PyObject *item = PyList_GetItem(m_list, m_cursor); // borrowed reference!
337 painter.setFont(fnt);
339 /* the user can supply tuples, in this case the first one will be displayed. */
340 if (PyTuple_Check(item))
341 item = PyTuple_GetItem(item, 0);
343 const char *string = PyString_Check(item) ? PyString_AsString(item) : "<not-a-string>";
345 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
347 painter.renderText(eRect(text_offset, m_itemsize), string);
350 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
356 void eListboxPythonStringContent::setList(PyObject *list)
359 if (!PyList_Check(list))
369 PyObject *eListboxPythonStringContent::getCurrentSelection()
375 PyObject *r = PyList_GetItem(m_list, m_cursor);
380 //////////////////////////////////////