void listbox_select_entry (WListbox * l, int dest) { GList *le; int pos; gboolean top_seen = FALSE; if (listbox_is_empty (l) || dest < 0) return; /* Special case */ for (pos = 0, le = g_queue_peek_head_link (l->list); le != NULL; pos++, le = g_list_next (le)) { if (pos == l->top) top_seen = TRUE; if (pos == dest) { l->pos = dest; if (!top_seen) l->top = l->pos; else { int lines = WIDGET (l)->lines; if (l->pos - l->top >= lines) l->top = l->pos - lines + 1; } return; } } /* If we are unable to find it, set decent values */ l->pos = l->top = 0; }
static void listbox_back (WListbox * l, gboolean wrap) { if (!listbox_is_empty (l)) { if (l->pos > 0) listbox_select_entry (l, l->pos - 1); else if (wrap) listbox_select_last (l); } }
static void listbox_fwd (WListbox * l, gboolean wrap) { if (!listbox_is_empty (l)) { if ((guint) l->pos + 1 < g_queue_get_length (l->list)) listbox_select_entry (l, l->pos + 1); else if (wrap) listbox_select_first (l); } }
/* Selects the last entry and scrolls the list to the bottom */ void listbox_select_last (WListbox * l) { int lines = WIDGET (l)->lines; int length = 0; if (!listbox_is_empty (l)) length = g_queue_get_length (l->list); l->pos = length > 0 ? length - 1 : 0; l->top = length > lines ? length - lines : 0; }
WLEntry * listbox_get_nth_item (const WListbox * l, int pos) { if (!listbox_is_empty (l) && pos >= 0) { GList *item; item = g_queue_peek_nth_link (l->list, (guint) pos); if (item != NULL) return LENTRY (item->data); } return NULL; }
/* Selects from base the pos element */ static int listbox_select_pos (WListbox * l, int base, int pos) { int last = 0; base += pos; if (!listbox_is_empty (l)) last = g_queue_get_length (l->list) - 1; base = min (base, last); return base; }
int listbox_search_text (WListbox * l, const char *text) { if (!listbox_is_empty (l)) { int i; GList *le; for (i = 0, le = g_queue_peek_head_link (l->list); le != NULL; i++, le = g_list_next (le)) { WLEntry *e = LENTRY (le->data); if (strcmp (e->text, text) == 0) return i; } } return (-1); }
static int listbox_check_hotkey (WListbox * l, int key) { if (!listbox_is_empty (l)) { int i; GList *le; for (i = 0, le = g_queue_peek_head_link (l->list); le != NULL; i++, le = g_list_next (le)) { WLEntry *e = LENTRY (le->data); if (e->hotkey == key) return i; } } return (-1); }
/** * Finds item by its 'data' slot. */ int listbox_search_data (WListbox * l, const void *data) { if (!listbox_is_empty (l)) { int i; GList *le; for (i = 0, le = g_queue_peek_head_link (l->list); le != NULL; i++, le = g_list_next (le)) { WLEntry *e = LENTRY (le->data); if (e->data == data) return i; } } return (-1); }
void listbox_remove_current (WListbox * l) { if (!listbox_is_empty (l)) { GList *current; int length; current = g_queue_peek_nth_link (l->list, (guint) l->pos); listbox_entry_free (LENTRY (current->data)); g_queue_delete_link (l->list, current); length = g_queue_get_length (l->list); if (length == 0) l->top = l->pos = 0; else if (l->pos >= length) l->pos = length - 1; } }
static void listbox_do_action (WListbox * l) { int action; if (listbox_is_empty (l)) return; if (l->callback != NULL) action = l->callback (l); else action = LISTBOX_DONE; if (action == LISTBOX_DONE) { WDialog *h = WIDGET (l)->owner; h->ret_value = B_ENTER; dlg_stop (h); } }
static int listbox_event (Gpm_Event * event, void *data) { WListbox *l = LISTBOX (data); Widget *w = WIDGET (data); if (!mouse_global_in_widget (event, w)) return MOU_UNHANDLED; /* Single click */ if ((event->type & GPM_DOWN) != 0) dlg_select_widget (l); if (listbox_is_empty (l)) return MOU_NORMAL; if ((event->type & (GPM_DOWN | GPM_DRAG)) != 0) { int ret = MOU_REPEAT; Gpm_Event local; int i; local = mouse_get_local (event, w); if (local.y < 1) for (i = -local.y; i >= 0; i--) listbox_back (l); else if (local.y > w->lines) for (i = local.y - w->lines; i > 0; i--) listbox_fwd (l); else if ((local.buttons & GPM_B_UP) != 0) { listbox_back (l); ret = MOU_NORMAL; } else if ((local.buttons & GPM_B_DOWN) != 0) { listbox_fwd (l); ret = MOU_NORMAL; } else listbox_select_entry (l, listbox_select_pos (l, l->top, local.y - 1)); /* We need to refresh ourselves since the dialog manager doesn't */ /* know about this event */ listbox_draw (l, TRUE); return ret; } /* Double click */ if ((event->type & (GPM_DOUBLE | GPM_UP)) == (GPM_UP | GPM_DOUBLE)) { Gpm_Event local; int action; local = mouse_get_local (event, w); dlg_select_widget (l); listbox_select_entry (l, listbox_select_pos (l, l->top, local.y - 1)); if (l->callback != NULL) action = l->callback (l); else action = LISTBOX_DONE; if (action == LISTBOX_DONE) { w->owner->ret_value = B_ENTER; dlg_stop (w->owner); } } return MOU_NORMAL; }