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()
33 DEFINE_REF(eListboxTestContent);
35 void eListboxTestContent::cursorHome()
40 void eListboxTestContent::cursorEnd()
45 int eListboxTestContent::cursorMove(int count)
51 else if (m_cursor > size())
56 int eListboxTestContent::cursorValid()
58 return m_cursor < size();
61 int eListboxTestContent::cursorSet(int n)
67 else if (m_cursor > size())
72 int eListboxTestContent::cursorGet()
77 void eListboxTestContent::cursorSave()
79 m_saved_cursor = m_cursor;
82 void eListboxTestContent::cursorRestore()
84 m_cursor = m_saved_cursor;
87 int eListboxTestContent::size()
92 RESULT eListboxTestContent::connectItemChanged(const Slot0<void> &itemChanged, ePtr<eConnection> &connection)
97 void eListboxTestContent::setSize(const eSize &size)
102 void eListboxTestContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
104 ePtr<gFont> fnt = new gFont("Arial", 14);
105 painter.clip(eRect(offset, m_size));
106 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
111 painter.setFont(fnt);
113 sprintf(string, "%d.)", m_cursor);
115 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
117 painter.renderText(eRect(text_offset, m_size), string);
120 style.drawFrame(painter, eRect(offset, m_size), eWindowStyle::frameListboxEntry);
126 //////////////////////////////////////
128 DEFINE_REF(eListboxStringContent);
130 eListboxStringContent::eListboxStringContent()
136 void eListboxStringContent::cursorHome()
138 m_cursor = m_list.begin();
142 void eListboxStringContent::cursorEnd()
144 m_cursor = m_list.end();
145 m_cursor_number = m_size;
148 int eListboxStringContent::cursorMove(int count)
152 while (count && (m_cursor != m_list.end()))
158 } else if (count < 0)
160 while (count && (m_cursor != m_list.begin()))
171 int eListboxStringContent::cursorValid()
173 return m_cursor != m_list.end();
176 int eListboxStringContent::cursorSet(int n)
184 int eListboxStringContent::cursorGet()
186 return m_cursor_number;
189 void eListboxStringContent::cursorSave()
191 m_saved_cursor = m_cursor;
192 m_saved_cursor_number = m_cursor_number;
195 void eListboxStringContent::cursorRestore()
197 m_cursor = m_saved_cursor;
198 m_cursor_number = m_saved_cursor_number;
201 int eListboxStringContent::size()
206 RESULT eListboxStringContent::connectItemChanged(const Slot0<void> &itemChanged, ePtr<eConnection> &connection)
211 void eListboxStringContent::setSize(const eSize &size)
216 void eListboxStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
218 ePtr<gFont> fnt = new gFont("Arial", 14);
219 painter.clip(eRect(offset, m_itemsize));
220 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
223 eDebug("item %d", m_cursor_number);
226 eDebug("is valid..");
227 painter.setFont(fnt);
229 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
231 painter.renderText(eRect(text_offset, m_itemsize), *m_cursor);
234 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
240 void eListboxStringContent::setList(std::list<std::string> &list)
243 m_size = list.size();
247 //////////////////////////////////////
249 DEFINE_REF(eListboxPythonStringContent);
251 eListboxPythonStringContent::eListboxPythonStringContent()
256 eListboxPythonStringContent::~eListboxPythonStringContent()
260 void eListboxPythonStringContent::cursorHome()
265 void eListboxPythonStringContent::cursorEnd()
270 int eListboxPythonStringContent::cursorMove(int count)
276 else if (m_cursor > size())
281 int eListboxPythonStringContent::cursorValid()
283 return m_cursor < size();
286 int eListboxPythonStringContent::cursorSet(int n)
292 else if (m_cursor > size())
297 int eListboxPythonStringContent::cursorGet()
302 void eListboxPythonStringContent::cursorSave()
304 m_saved_cursor = m_cursor;
307 void eListboxPythonStringContent::cursorRestore()
309 m_cursor = m_saved_cursor;
312 int eListboxPythonStringContent::size()
316 return PyList_Size(m_list);
319 RESULT eListboxPythonStringContent::connectItemChanged(const Slot0<void> &itemChanged, ePtr<eConnection> &connection)
324 void eListboxPythonStringContent::setSize(const eSize &size)
329 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
331 ePtr<gFont> fnt = new gFont("Arial", 14);
332 painter.clip(eRect(offset, m_itemsize));
333 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
336 if (m_list && cursorValid())
338 PyObject *item = PyList_GetItem(m_list, m_cursor); // borrowed reference!
339 painter.setFont(fnt);
341 /* the user can supply tuples, in this case the first one will be displayed. */
342 if (PyTuple_Check(item))
343 item = PyTuple_GetItem(item, 0);
345 const char *string = PyString_Check(item) ? PyString_AsString(item) : "<not-a-string>";
347 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
349 painter.renderText(eRect(text_offset, m_itemsize), string);
352 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
358 void eListboxPythonStringContent::setList(PyObject *list)
361 if (!PyList_Check(list))
371 PyObject *eListboxPythonStringContent::getCurrentSelection()
377 PyObject *r = PyList_GetItem(m_list, m_cursor);
382 //////////////////////////////////////