diff options
Diffstat (limited to 'src/listbox.c')
-rw-r--r-- | src/listbox.c | 75 |
1 files changed, 41 insertions, 34 deletions
diff --git a/src/listbox.c b/src/listbox.c index 38e7647..12c45cc 100644 --- a/src/listbox.c +++ b/src/listbox.c @@ -36,6 +36,9 @@ #include "calcurse.h" +static void listbox_fix_sel(struct listbox *, int); +static void listbox_sel_in_view(struct listbox *); + void listbox_init(struct listbox *lb, int y, int x, int h, int w, const char *label, listbox_fn_item_type_t fn_type, listbox_fn_item_height_t fn_height, @@ -60,21 +63,6 @@ void listbox_delete(struct listbox *lb) mem_free(lb->ch); } -static void listbox_fix_visible_region(struct listbox *lb) -{ - int i; - - wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[lb->item_sel]); - wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[lb->item_sel + 1] - 1); - - i = lb->item_sel - 1; - while (i >= 0 && lb->type[i] != LISTBOX_ROW_TEXT) { - wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[i]); - wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[i + 1] - 1); - i++; - } -} - void listbox_resize(struct listbox *lb, int y, int x, int h, int w) { EXIT_IF(lb == NULL, "null pointer"); @@ -83,7 +71,7 @@ void listbox_resize(struct listbox *lb, int y, int x, int h, int w) if (lb->item_sel < 0) return; - listbox_fix_visible_region(lb); + listbox_sel_in_view(lb); } void listbox_set_cb_data(struct listbox *lb, void *cb_data) @@ -91,14 +79,11 @@ void listbox_set_cb_data(struct listbox *lb, void *cb_data) lb->cb_data = cb_data; } -static void listbox_fix_sel(struct listbox *, int); - void listbox_load_items(struct listbox *lb, int item_count) { int i, ch; lb->item_count = item_count; - if (item_count == 0) { lb->item_sel = -1; return; @@ -114,14 +99,13 @@ void listbox_load_items(struct listbox *lb, int item_count) ch += lb->fn_height(i, lb->cb_data); } lb->ch[item_count] = ch; + + /* The pad lines: 0,.., ch - 1. */ wins_scrollwin_set_pad(&(lb->sw), ch); - if (item_count > 0 && lb->item_sel < 0) - lb->item_sel = 0; - else if (lb->item_sel >= item_count) - lb->item_sel = item_count - 1; + /* Adjust the selection. */ listbox_fix_sel(lb, 1); - listbox_fix_visible_region(lb); + listbox_sel_in_view(lb); } void listbox_draw_deco(struct listbox *lb, int hilt) @@ -148,6 +132,7 @@ int listbox_get_sel(struct listbox *lb) return lb->item_sel; } +/* Avoid non-text items. */ static void listbox_fix_sel(struct listbox *lb, int direction) { int did_flip = 0; @@ -157,6 +142,11 @@ static void listbox_fix_sel(struct listbox *lb, int direction) direction = direction > 0 ? 1 : -1; + if (lb->item_sel < 0) + lb->item_sel = 0; + else if (lb->item_sel >= lb->item_count) + lb->item_sel = lb->item_count - 1; + while (lb->type[lb->item_sel] != LISTBOX_ROW_TEXT) { if ((direction == -1 && lb->item_sel == 0) || (direction == 1 && lb->item_sel == lb->item_count - 1)) { @@ -179,23 +169,40 @@ void listbox_set_sel(struct listbox *lb, unsigned pos) if (lb->item_sel < 0) return; - listbox_fix_visible_region(lb); + listbox_sel_in_view(lb); +} + +void listbox_item_in_view(struct listbox *lb, int item) +{ + int first_line = lb->ch[item]; + int last_line = lb->ch[item + 1] - 1; + + wins_scrollwin_in_view(&(lb->sw), first_line); + if (last_line != first_line) + wins_scrollwin_in_view(&(lb->sw), last_line); } -void listbox_sel_move(struct listbox *lb, int delta) +/* Keep the selection in view. */ +static void listbox_sel_in_view(struct listbox *lb) { + listbox_item_in_view(lb, lb->item_sel); +} + +/* Returns true if the move succeeded. */ +int listbox_sel_move(struct listbox *lb, int delta) +{ + + int saved_sel = lb->item_sel; + if (lb->item_count == 0) - return; + return 0; lb->item_sel += delta; - if (lb->item_sel < 0) - lb->item_sel = 0; - else if (lb->item_sel >= lb->item_count) - lb->item_sel = lb->item_count - 1; - listbox_fix_sel(lb, delta); if (lb->item_sel < 0) - return; + return 0; + + listbox_sel_in_view(lb); - listbox_fix_visible_region(lb); + return lb->item_sel != saved_sel; } |