1 #include <lib/gui/elistbox.h>
2 #include <lib/gui/elistboxcontent.h>
3 #include <lib/gdi/font.h>
4 #include <lib/python/python.h>
7 The basic idea is to have an interface which gives all relevant list
8 processing functions, and can be used by the listbox to browse trough
11 The listbox directly uses the implemented cursor. It tries hard to avoid
12 iterating trough the (possibly very large) list, so it should be O(1),
13 i.e. the performance should not be influenced by the size of the list.
15 The list interface knows how to draw the current entry to a specified
16 offset. Different interfaces can be used to adapt different lists,
17 pre-filter lists on the fly etc.
19 cursorSave/Restore is used to avoid re-iterating the list on redraw.
20 The current selection is always selected as cursor position, the
21 cursor is then positioned to the start, and then iterated. This gives
22 at most 2x m_items_per_page cursor movements per redraw, indepenent
23 of the size of the list.
25 Although cursorSet is provided, it should be only used when there is no
26 other way, as it involves iterating trough the list.
29 iListboxContent::~iListboxContent()
33 iListboxContent::iListboxContent(): m_listbox(0)
37 void iListboxContent::setListbox(eListbox *lb)
40 m_listbox->setItemHeight(getItemHeight());
43 int iListboxContent::currentCursorSelectable()
48 //////////////////////////////////////
50 DEFINE_REF(eListboxPythonStringContent);
52 eListboxPythonStringContent::eListboxPythonStringContent(): m_itemheight(25)
56 eListboxPythonStringContent::~eListboxPythonStringContent()
61 void eListboxPythonStringContent::cursorHome()
66 void eListboxPythonStringContent::cursorEnd()
71 int eListboxPythonStringContent::cursorMove(int count)
77 else if (m_cursor > size())
82 int eListboxPythonStringContent::cursorValid()
84 return m_cursor < size();
87 int eListboxPythonStringContent::cursorSet(int n)
93 else if (m_cursor > size())
98 int eListboxPythonStringContent::cursorGet()
103 int eListboxPythonStringContent::currentCursorSelectable()
105 if (m_list && cursorValid())
107 ePyObject item = PyList_GET_ITEM(m_list, m_cursor);
108 if (!PyTuple_Check(item))
110 if (PyTuple_Size(item) >= 2)
116 void eListboxPythonStringContent::cursorSave()
118 m_saved_cursor = m_cursor;
121 void eListboxPythonStringContent::cursorRestore()
123 m_cursor = m_saved_cursor;
126 int eListboxPythonStringContent::size()
130 return PyList_Size(m_list);
133 void eListboxPythonStringContent::setSize(const eSize &size)
138 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
140 ePtr<gFont> fnt = new gFont("Regular", 20);
141 painter.clip(eRect(offset, m_itemsize));
142 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
144 eListboxStyle *local_style = 0;
146 /* get local listbox style, if present */
148 local_style = m_listbox->getLocalStyle();
150 /* if we have a local background color set, use that. */
151 if (local_style && local_style->m_background_color_set)
152 painter.setBackgroundColor(local_style->m_background_color);
154 /* same for foreground */
155 if (local_style && local_style->m_foreground_color_set)
156 painter.setForegroundColor(local_style->m_foreground_color);
158 /* if we have no transparent background */
159 if (!local_style || !local_style->m_transparent_background)
161 /* blit background picture, if available (otherwise, clear only) */
162 if (local_style && local_style->m_background)
163 painter.blit(local_style->m_background, offset, eRect(), 0);
168 if (local_style && local_style->m_background)
169 painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST);
172 if (m_list && cursorValid())
175 ePyObject item = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference!
176 painter.setFont(fnt);
178 /* the user can supply tuples, in this case the first one will be displayed. */
179 if (PyTuple_Check(item))
181 if (PyTuple_Size(item) == 1)
183 item = PyTuple_GET_ITEM(item, 0);
186 if (selected && local_style && local_style->m_selection)
187 painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST);
192 int half_height = m_itemsize.height() / 2;
193 painter.fill(eRect(offset.x() + half_height, offset.y() + half_height - 2, m_itemsize.width() - m_itemsize.height(), 4));
196 const char *string = PyString_Check(item) ? PyString_AsString(item) : "<not-a-string>";
197 ePoint text_offset = offset + (selected ? ePoint(2, 2) : ePoint(1, 1));
199 painter.setForegroundColor(gRGB(0x808080));
200 painter.renderText(eRect(text_offset, m_itemsize), string);
203 if (selected && (!local_style || !local_style->m_selection))
204 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
210 void eListboxPythonStringContent::setList(ePyObject list)
213 if (!PyList_Check(list))
215 m_list = ePyObject();
223 m_listbox->entryReset(false);
226 PyObject *eListboxPythonStringContent::getCurrentSelection()
228 if (!(m_list && cursorValid()))
231 ePyObject r = PyList_GET_ITEM(m_list, m_cursor);
236 void eListboxPythonStringContent::invalidateEntry(int index)
239 m_listbox->entryChanged(index);
242 void eListboxPythonStringContent::invalidate()
248 m_listbox->moveSelectionTo(s?s-1:0);
249 m_listbox->invalidate();
253 //////////////////////////////////////
255 void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
257 ePtr<gFont> fnt = new gFont("Regular", 20);
258 ePtr<gFont> fnt2 = new gFont("Regular", 16);
259 eRect itemrect(offset, m_itemsize);
260 eListboxStyle *local_style = 0;
262 painter.clip(itemrect);
263 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
265 /* get local listbox style, if present */
267 local_style = m_listbox->getLocalStyle();
269 /* if we have a local background color set, use that. */
270 if (local_style && local_style->m_background_color_set)
271 painter.setBackgroundColor(local_style->m_background_color);
273 /* same for foreground */
274 if (local_style && local_style->m_foreground_color_set)
275 painter.setForegroundColor(local_style->m_foreground_color);
277 if (!local_style || !local_style->m_transparent_background)
278 /* if we have no transparent background */
280 /* blit background picture, if available (otherwise, clear only) */
281 if (local_style && local_style->m_background)
282 painter.blit(local_style->m_background, offset, eRect(), 0);
287 if (local_style && local_style->m_background)
288 painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST);
291 if (m_list && cursorValid())
293 /* get current list item */
294 ePyObject item = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference!
295 ePyObject text, value;
296 painter.setFont(fnt);
298 if (selected && local_style && local_style->m_selection)
299 painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST);
301 /* the first tuple element is a string for the left side.
302 the second one will be called, and the result shall be an tuple.
305 the first one is the type (string).
306 the second one is the value. */
307 if (PyTuple_Check(item))
309 /* handle left part. get item from tuple, convert to string, display. */
311 text = PyTuple_GET_ITEM(item, 0);
312 text = PyObject_Str(text); /* creates a new object - old object was borrowed! */
313 const char *string = (text && PyString_Check(text)) ? PyString_AsString(text) : "<not-a-string>";
314 eSize item_left = eSize(m_seperation, m_itemsize.height());
315 eSize item_right = eSize(m_itemsize.width() - m_seperation, m_itemsize.height());
316 painter.renderText(eRect(offset, item_left), string, gPainter::RT_HALIGN_LEFT);
319 /* when we have no label, align value to the left. (FIXME:
320 don't we want to specifiy this individually?) */
321 int value_alignment_left = !*string;
323 /* now, handle the value. get 2nd part from tuple*/
324 value = PyTuple_GET_ITEM(item, 1);
327 ePyObject args = PyTuple_New(1);
328 PyTuple_SET_ITEM(args, 0, PyInt_FromLong(selected));
330 /* CallObject will call __call__ which should return the value tuple */
331 value = PyObject_CallObject(value, args);
333 if (PyErr_Occurred())
337 /* the PyInt was stolen. */
340 /* check if this is really a tuple */
341 if (value && PyTuple_Check(value))
343 /* convert type to string */
344 ePyObject type = PyTuple_GET_ITEM(value, 0);
345 const char *atype = (type && PyString_Check(type)) ? PyString_AsString(type) : 0;
349 if (!strcmp(atype, "text"))
351 ePyObject pvalue = PyTuple_GET_ITEM(value, 1);
352 const char *value = (pvalue && PyString_Check(pvalue)) ? PyString_AsString(pvalue) : "<not-a-string>";
353 painter.setFont(fnt2);
354 if (value_alignment_left)
355 painter.renderText(eRect(offset, item_right), value, gPainter::RT_HALIGN_LEFT);
357 painter.renderText(eRect(offset + eSize(m_seperation, 0), item_right), value, gPainter::RT_HALIGN_RIGHT);
359 /* pvalue is borrowed */
360 } else if (!strcmp(atype, "slider"))
362 ePyObject pvalue = PyTuple_GET_ITEM(value, 1);
363 ePyObject psize = PyTuple_GET_ITEM(value, 2);
365 /* convert value to Long. fallback to -1 on error. */
366 int value = (pvalue && PyInt_Check(pvalue)) ? PyInt_AsLong(pvalue) : -1;
367 int size = (pvalue && PyInt_Check(psize)) ? PyInt_AsLong(psize) : 100;
369 /* calc. slider length */
370 int width = item_right.width() * value / size;
371 int height = item_right.height();
375 //painter.fill(eRect(offset.x() + m_seperation, offset.y(), width, height));
376 //hack - make it customizable
377 painter.fill(eRect(offset.x() + m_seperation, offset.y() + 5, width, height-10));
379 /* pvalue is borrowed */
380 } else if (!strcmp(atype, "mtext"))
382 ePyObject pvalue = PyTuple_GET_ITEM(value, 1);
383 const char *text = (pvalue && PyString_Check(pvalue)) ? PyString_AsString(pvalue) : "<not-a-string>";
384 int xoffs = value_alignment_left ? 0 : m_seperation;
385 ePtr<eTextPara> para = new eTextPara(eRect(offset + eSize(xoffs, 0), item_right));
387 para->renderString(text, 0);
388 para->realign(value_alignment_left ? eTextPara::dirLeft : eTextPara::dirRight);
389 int glyphs = para->size();
393 if (PyTuple_Size(value) >= 3)
394 plist = PyTuple_GET_ITEM(value, 2);
398 if (plist && PyList_Check(plist))
399 entries = PyList_Size(plist);
401 for (int i = 0; i < entries; ++i)
403 ePyObject entry = PyList_GET_ITEM(plist, i);
404 int num = PyInt_Check(entry) ? PyInt_AsLong(entry) : -1;
406 if ((num < 0) || (num >= glyphs))
407 eWarning("glyph index %d in PythonConfigList out of bounds!", num);
410 para->setGlyphFlag(num, GS_INVERT);
412 bbox = para->getGlyphBBox(num);
413 bbox = eRect(bbox.left(), offset.y(), bbox.width(), m_itemsize.height());
416 /* entry is borrowed */
419 painter.renderPara(para, ePoint(0, 0));
420 /* pvalue is borrowed */
421 /* plist is 0 or borrowed */
424 /* type is borrowed */
426 eWarning("eListboxPythonConfigContent: second value of tuple is not a tuple.");
427 /* value is borrowed */
430 if (selected && (!local_style || !local_style->m_selection))
431 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
437 int eListboxPythonConfigContent::currentCursorSelectable()
439 return eListboxPythonStringContent::currentCursorSelectable();
442 //////////////////////////////////////
444 /* todo: make a real infrastructure here! */
445 RESULT SwigFromPython(ePtr<gPixmap> &res, PyObject *obj);
447 eListboxPythonMultiContent::eListboxPythonMultiContent()
448 :m_clip(gRegion::invalidRegion()), m_old_clip(gRegion::invalidRegion())
452 eListboxPythonMultiContent::~eListboxPythonMultiContent()
454 Py_XDECREF(m_buildFunc);
455 Py_XDECREF(m_selectableFunc);
458 void eListboxPythonMultiContent::setSelectionClip(eRect &rect, bool update)
460 m_selection_clip = rect;
462 rect.moveBy(ePoint(0, m_listbox->getEntryTop()));
467 if (update && m_listbox)
468 m_listbox->entryChanged(m_cursor);
471 static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *local_style, ePyObject pforeColor, ePyObject pbackColor, ePyObject pbackColorSelected, int selected, gRegion &rc, eRect &sel_clip)
473 if (selected && sel_clip.valid())
476 painter.clip(rc-sel_clip);
479 int color = PyInt_AsLong(pbackColor);
480 painter.setBackgroundColor(gRGB(color));
481 } // transparent background?
482 else if (local_style && local_style->m_transparent_background)
484 // if we have a local background color set, use that.
485 else if (local_style && local_style->m_background_color_set)
486 painter.setBackgroundColor(local_style->m_background_color);
488 style.setStyle(painter, eWindowStyle::styleListboxNormal);
492 painter.clip(rc&sel_clip);
493 style.setStyle(painter, eWindowStyle::styleListboxSelected);
494 if (pbackColorSelected)
496 int color = PyInt_AsLong(pbackColorSelected);
497 painter.setBackgroundColor(gRGB(color));
506 style.setStyle(painter, eWindowStyle::styleListboxSelected);
507 if (pbackColorSelected)
509 int color = PyInt_AsLong(pbackColorSelected);
510 painter.setBackgroundColor(gRGB(color));
517 style.setStyle(painter, eWindowStyle::styleListboxNormal);
520 int color = PyInt_AsLong(pbackColor);
521 painter.setBackgroundColor(gRGB(color));
522 }/* if we have a local background color set, use that. */
523 else if (local_style)
525 if (local_style->m_transparent_background)
527 else if (local_style->m_background_color_set)
528 painter.setBackgroundColor(local_style->m_background_color);
530 /* if we have no transparent background */
537 int color = PyInt_AsLong(pforeColor);
538 painter.setForegroundColor(gRGB(color));
539 }/* if we have a local foreground color set, use that. */
540 else if (local_style && local_style->m_foreground_color_set)
541 painter.setForegroundColor(local_style->m_foreground_color);
544 void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
546 gRegion itemregion(eRect(offset, m_itemsize));
547 eListboxStyle *local_style = 0;
548 eRect sel_clip(m_selection_clip);
549 if (sel_clip.valid())
550 sel_clip.moveBy(offset);
552 /* get local listbox style, if present */
554 local_style = m_listbox->getLocalStyle();
556 painter.clip(itemregion);
558 clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip);
562 if (m_list && cursorValid())
564 items = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference!
568 if (PyCallable_Check(m_buildFunc)) // when we have a buildFunc then call it
570 if (PyTuple_Check(items))
571 items = PyObject_CallObject(m_buildFunc, items);
573 eDebug("items is no tuple");
576 eDebug("buildfunc is not callable");
581 eDebug("eListboxPythonMultiContent: error getting item %d", m_cursor);
585 if (!PyList_Check(items))
587 eDebug("eListboxPythonMultiContent: list entry %d is not a list", m_cursor);
591 int size = PyList_Size(items);
592 for (int i = 1; i < size; ++i)
594 ePyObject item = PyList_GET_ITEM(items, i); // borrowed reference!
595 bool reset_colors=false;
599 eDebug("eListboxPythonMultiContent: ?");
603 if (!PyTuple_Check(item))
605 eDebug("eListboxPythonMultiContent did not receive a tuple.");
609 int size = PyTuple_Size(item);
613 eDebug("eListboxPythonMultiContent receive empty tuple.");
617 int type = PyInt_AsLong(PyTuple_GET_ITEM(item, 0));
621 case TYPE_TEXT: // text
624 (0, x, y, width, height, fnt, flags, "bla" [, color, backColor, backColorSelected, borderWidth, borderColor] )
626 ePyObject px = PyTuple_GET_ITEM(item, 1),
627 py = PyTuple_GET_ITEM(item, 2),
628 pwidth = PyTuple_GET_ITEM(item, 3),
629 pheight = PyTuple_GET_ITEM(item, 4),
630 pfnt = PyTuple_GET_ITEM(item, 5),
631 pflags = PyTuple_GET_ITEM(item, 6),
632 pstring = PyTuple_GET_ITEM(item, 7),
633 pforeColor, pbackColor, pbackColorSelected, pborderWidth, pborderColor;
635 if (!(px && py && pwidth && pheight && pfnt && pflags && pstring))
637 eDebug("eListboxPythonMultiContent received too small tuple (must be (TYPE_TEXT, x, y, width, height, fnt, flags, string [, color, backColor, backColorSelected, borderWidth, borderColor])");
643 pforeColor = PyTuple_GET_ITEM(item, 8);
644 if (pforeColor == Py_None)
645 pforeColor=ePyObject();
649 pbackColor = PyTuple_GET_ITEM(item, 9);
650 if (pbackColor == Py_None)
651 pbackColor=ePyObject();
655 pbackColorSelected = PyTuple_GET_ITEM(item, 10);
656 if (pbackColorSelected == Py_None)
657 pbackColorSelected=ePyObject();
660 pborderWidth = PyTuple_GET_ITEM(item, 11);
662 pborderColor = PyTuple_GET_ITEM(item, 12);
664 const char *string = (PyString_Check(pstring)) ? PyString_AsString(pstring) : "<not-a-string>";
665 int x = PyInt_AsLong(px) + offset.x();
666 int y = PyInt_AsLong(py) + offset.y();
667 int width = PyInt_AsLong(pwidth);
668 int height = PyInt_AsLong(pheight);
669 int flags = PyInt_AsLong(pflags);
670 int fnt = PyInt_AsLong(pfnt);
671 int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 0;
673 if (m_font.find(fnt) == m_font.end())
675 eDebug("eListboxPythonMultiContent: specified font %d was not found!", fnt);
679 eRect rect(x+bwidth, y+bwidth, width-bwidth*2, height-bwidth*2);
681 if (pbackColor || pbackColorSelected || pforeColor)
684 clearRegion(painter, style, local_style, pforeColor, pbackColor, pbackColorSelected, selected, rc, sel_clip);
688 painter.setFont(m_font[fnt]);
689 painter.renderText(rect, string, flags);
695 eRect rect(eRect(x, y, width, height));
699 int color = PyInt_AsLong(pborderColor);
700 painter.setForegroundColor(gRGB(color));
702 else if (pforeColor) // reset to normal color
703 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
705 rect.setRect(x, y, width, bwidth);
708 rect.setRect(x, y+bwidth, bwidth, height-bwidth);
711 rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth);
714 rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth);
721 case TYPE_PROGRESS: // Progress
724 (1, x, y, width, height, filled_percent [, borderWidth, foreColor, backColor, backColorSelected] )
726 ePyObject px = PyTuple_GET_ITEM(item, 1),
727 py = PyTuple_GET_ITEM(item, 2),
728 pwidth = PyTuple_GET_ITEM(item, 3),
729 pheight = PyTuple_GET_ITEM(item, 4),
730 pfilled_perc = PyTuple_GET_ITEM(item, 5),
731 pborderWidth, pforeColor, pbackColor, pbackColorSelected;
733 if (!(px && py && pwidth && pheight && pfilled_perc))
735 eDebug("eListboxPythonMultiContent received too small tuple (must be (TYPE_PROGRESS, x, y, width, height, filled percent [,border width, foreColor, backColor, backColorSelected]))");
740 pborderWidth = PyTuple_GET_ITEM(item, 6);
742 pforeColor = PyTuple_GET_ITEM(item, 7);
745 pbackColor = PyTuple_GET_ITEM(item, 8);
746 if (pbackColor == Py_None)
747 pbackColor=ePyObject();
751 pbackColorSelected = PyTuple_GET_ITEM(item, 9);
752 if (pbackColorSelected == Py_None)
753 pbackColorSelected=ePyObject();
756 int x = PyInt_AsLong(px) + offset.x();
757 int y = PyInt_AsLong(py) + offset.y();
758 int width = PyInt_AsLong(pwidth);
759 int height = PyInt_AsLong(pheight);
760 int filled = PyInt_AsLong(pfilled_perc);
761 int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 2;
763 eRect rect(x, y, width, height);
765 if (pbackColor || pbackColorSelected || pforeColor)
768 clearRegion(painter, style, local_style, pforeColor, pbackColor, pbackColorSelected, selected, rc, sel_clip);
773 rect.setRect(x, y, width, bwidth);
776 rect.setRect(x, y+bwidth, bwidth, height-bwidth);
779 rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth);
782 rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth);
786 rect.setRect(x+bwidth, y+bwidth, (width-bwidth*2) * filled / 100, height-bwidth*2);
793 case TYPE_PIXMAP_ALPHATEST:
794 case TYPE_PIXMAP: // pixmap
797 (2, x, y, width, height, pixmap [, backColor, backColorSelected] )
800 ePyObject px = PyTuple_GET_ITEM(item, 1),
801 py = PyTuple_GET_ITEM(item, 2),
802 pwidth = PyTuple_GET_ITEM(item, 3),
803 pheight = PyTuple_GET_ITEM(item, 4),
804 ppixmap = PyTuple_GET_ITEM(item, 5),
805 pbackColor, pbackColorSelected;
807 if (!(px && py && pwidth && pheight && ppixmap))
809 eDebug("eListboxPythonMultiContent received too small tuple (must be (TYPE_PIXMAP, x, y, width, height, pixmap [, backColor, backColorSelected] ))");
813 int x = PyInt_AsLong(px) + offset.x();
814 int y = PyInt_AsLong(py) + offset.y();
815 int width = PyInt_AsLong(pwidth);
816 int height = PyInt_AsLong(pheight);
817 ePtr<gPixmap> pixmap;
818 if (SwigFromPython(pixmap, ppixmap))
820 eDebug("eListboxPythonMultiContent (Pixmap) get pixmap failed");
826 pbackColor = PyTuple_GET_ITEM(item, 6);
827 if (pbackColor == Py_None)
828 pbackColor=ePyObject();
832 pbackColorSelected = PyTuple_GET_ITEM(item, 7);
833 if (pbackColorSelected == Py_None)
834 pbackColorSelected=ePyObject();
837 eRect rect(x, y, width, height);
839 if (pbackColor || pbackColorSelected)
842 clearRegion(painter, style, local_style, ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip);
846 painter.blit(pixmap, rect.topLeft(), rect, (type == TYPE_PIXMAP_ALPHATEST) ? gPainter::BT_ALPHATEST : 0);
851 eWarning("eListboxPythonMultiContent received unknown type (%d)", type);
855 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
860 style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
863 if (m_buildFunc && PyCallable_Check(m_buildFunc) && items)
869 void eListboxPythonMultiContent::setBuildFunc(ePyObject cb)
871 Py_XDECREF(m_buildFunc);
873 Py_XINCREF(m_buildFunc);
876 void eListboxPythonMultiContent::setSelectableFunc(ePyObject cb)
878 Py_XDECREF(m_selectableFunc);
880 Py_XINCREF(m_selectableFunc);
883 int eListboxPythonMultiContent::currentCursorSelectable()
885 /* each list-entry is a list of tuples. if the first of these is none, it's not selectable */
886 if (m_list && cursorValid())
888 if (m_selectableFunc && PyCallable_Check(m_selectableFunc))
890 ePyObject args = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference!
891 if (PyTuple_Check(args))
893 ePyObject ret = PyObject_CallObject(m_selectableFunc, args);
895 return ret == Py_True;
896 eDebug("call m_selectableFunc failed!!! assume not callable");
899 eDebug("m_list[m_cursor] is not a tuple!!! assume not callable");
903 ePyObject item = PyList_GET_ITEM(m_list, m_cursor);
904 if (PyList_Check(item))
906 item = PyList_GET_ITEM(item, 0);
910 else if (m_buildFunc && PyCallable_Check(m_buildFunc))
917 void eListboxPythonMultiContent::setFont(int fnt, gFont *font)
925 void eListboxPythonMultiContent::setItemHeight(int height)
927 m_itemheight = height;
929 m_listbox->setItemHeight(height);
932 void eListboxPythonMultiContent::setList(ePyObject list)
934 m_old_clip = m_clip = gRegion::invalidRegion();
935 eListboxPythonStringContent::setList(list);
938 void eListboxPythonMultiContent::updateClip(gRegion &clip)
943 if (m_old_clip.valid() && !(m_clip-m_old_clip).empty())
944 m_clip -= m_old_clip;
948 m_old_clip = m_clip = gRegion::invalidRegion();