+
+ if (m_items_per_page < 0) /* TODO: whyever - our size could be invalid, or itemheigh could be wrongly specified. */
+ m_items_per_page = 0;
+
+ moveSelection(justCheck);
+}
+
+void eListbox::setItemHeight(int h)
+{
+ if (h)
+ m_itemheight = h;
+ else
+ m_itemheight = 20;
+ recalcSize();
+}
+
+void eListbox::setSelectionEnable(int en)
+{
+ if (m_selection_enabled == en)
+ return;
+ m_selection_enabled = en;
+ entryChanged(m_selected); /* redraw current entry */
+}
+
+void eListbox::entryAdded(int index)
+{
+ if (m_content && (m_content->size() % m_items_per_page) == 1)
+ m_content_changed=true;
+ /* manage our local pointers. when the entry was added before the current position, we have to advance. */
+
+ /* we need to check <= - when the new entry has the (old) index of the cursor, the cursor was just moved down. */
+ if (index <= m_selected)
+ ++m_selected;
+ if (index <= m_top)
+ ++m_top;
+
+ /* we have to check wether our current cursor is gone out of the screen. */
+ /* moveSelection will check for this case */
+ moveSelection(justCheck);
+
+ /* now, check if the new index is visible. */
+ if ((m_top <= index) && (index < (m_top + m_items_per_page)))
+ {
+ /* todo, calc exact invalidation... */
+ invalidate();
+ }
+}
+
+void eListbox::entryRemoved(int index)
+{
+ if (m_content && !(m_content->size() % m_items_per_page))
+ m_content_changed=true;
+
+ if (index == m_selected && m_content)
+ m_selected = m_content->cursorGet();
+
+ if (m_content && m_content->cursorGet() >= m_content->size())
+ moveSelection(moveUp);
+ else
+ moveSelection(justCheck);
+
+ if ((m_top <= index) && (index < (m_top + m_items_per_page)))
+ {
+ /* todo, calc exact invalidation... */
+ invalidate();
+ }
+}
+
+void eListbox::entryChanged(int index)
+{
+ if ((m_top <= index) && (index < (m_top + m_items_per_page)))
+ {
+ gRegion inv = eRect(0, m_itemheight * (index-m_top), size().width(), m_itemheight);
+ invalidate(inv);
+ }
+}
+
+void eListbox::entryReset(bool selectionHome)
+{
+ m_content_changed = true;
+ m_prev_scrollbar_page = -1;
+ int oldsel;
+
+ if (selectionHome)
+ {
+ if (m_content)
+ m_content->cursorHome();
+ m_top = 0;
+ m_selected = 0;
+ }
+
+ if (m_content && (m_selected >= m_content->size()))
+ {
+ if (m_content->size())
+ m_selected = m_content->size() - 1;
+ else
+ m_selected = 0;
+ m_content->cursorSet(m_selected);
+ }
+
+ oldsel = m_selected;
+ moveSelection(justCheck);
+ /* if oldsel != m_selected, selectionChanged was already
+ emitted in moveSelection. we want it in any case, so otherwise,
+ emit it now. */
+ if (oldsel == m_selected)
+ /* emit */ selectionChanged();
+ invalidate();
+}
+
+void eListbox::setBackgroundColor(gRGB &col)
+{
+ m_style.m_background_color = col;
+ m_style.m_background_color_set = 1;
+}
+
+void eListbox::setBackgroundColorSelected(gRGB &col)
+{
+ m_style.m_background_color_selected = col;
+ m_style.m_background_color_selected_set = 1;
+}
+
+void eListbox::setForegroundColor(gRGB &col)
+{
+ m_style.m_foreground_color = col;
+ m_style.m_foreground_color_set = 1;
+}
+
+void eListbox::setForegroundColorSelected(gRGB &col)
+{
+ m_style.m_foreground_color_selected = col;
+ m_style.m_foreground_color_selected_set = 1;
+}
+
+void eListbox::setBackgroundPicture(ePtr<gPixmap> &pm)
+{
+ m_style.m_background = pm;
+}
+
+void eListbox::setSelectionPicture(ePtr<gPixmap> &pm)
+{
+ m_style.m_selection = pm;
+}
+
+void eListbox::invalidate(const gRegion ®ion)
+{
+ gRegion tmp(region);
+ if (m_content)
+ m_content->updateClip(tmp);
+ eWidget::invalidate(tmp);
+}
+
+struct eListboxStyle *eListbox::getLocalStyle(void)
+{
+ /* transparency is set directly in the widget */
+ m_style.m_transparent_background = isTransparent();
+ return &m_style;