Refactor listbox code

The changes are related to the selected item and the visible lines in
the scroll window viewport.

In particular, the function listbox_fix_visible_region() has been
eliminated, and functions previously only called by it have been
removed. It performed several tasks that are now elsewhere. One was
removed in an earlier commit (scroll window pad improvement). The task
of making a multi-line item visible has been moved to
listbox_item_in_view(). The task of making a caption line above a text
line visible is listbox specific (for the ap_list) and will be moved to
ui_day_sel_move(), where it is needed.

Boundary checks for the listbox selection have been moved to
listbox_fix_sel().

For future use listbox_sel_move() returns success or failure.

The function wins_scrollwin_ensure_visible() has been renamed
wins_scrollwin_in_view().

Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lars Henriksen 2019-03-16 08:31:12 +01:00 committed by Lukas Fleischer
parent 576994de00
commit df2cb2a9c0
3 changed files with 49 additions and 40 deletions

View File

@ -580,8 +580,8 @@ struct window {
/* Generic scrolling window structure. */ /* Generic scrolling window structure. */
struct scrollwin { struct scrollwin {
WINDOW *win; WINDOW *win; /* viewport */
WINDOW *inner; WINDOW *inner; /* pad */
int y; int y;
int x; int x;
int h; int h;
@ -936,7 +936,8 @@ void listbox_draw_deco(struct listbox *, int);
void listbox_display(struct listbox *, int); void listbox_display(struct listbox *, int);
int listbox_get_sel(struct listbox *); int listbox_get_sel(struct listbox *);
void listbox_set_sel(struct listbox *, unsigned); void listbox_set_sel(struct listbox *, unsigned);
void listbox_sel_move(struct listbox *, int); void listbox_item_in_view(struct listbox *, int);
int listbox_sel_move(struct listbox *, int);
/* mem.c */ /* mem.c */
void *xmalloc(size_t); void *xmalloc(size_t);
@ -1271,7 +1272,7 @@ void wins_scrollwin_draw_deco(struct scrollwin *, int);
void wins_scrollwin_display(struct scrollwin *, int); void wins_scrollwin_display(struct scrollwin *, int);
void wins_scrollwin_up(struct scrollwin *, int); void wins_scrollwin_up(struct scrollwin *, int);
void wins_scrollwin_down(struct scrollwin *, int); void wins_scrollwin_down(struct scrollwin *, int);
void wins_scrollwin_ensure_visible(struct scrollwin *, unsigned); void wins_scrollwin_in_view(struct scrollwin *, unsigned);
void wins_resize(void); void wins_resize(void);
void wins_resize_panels(void); void wins_resize_panels(void);
void wins_show(WINDOW *, const char *); void wins_show(WINDOW *, const char *);

View File

@ -36,6 +36,9 @@
#include "calcurse.h" #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, void listbox_init(struct listbox *lb, int y, int x, int h, int w,
const char *label, listbox_fn_item_type_t fn_type, const char *label, listbox_fn_item_type_t fn_type,
listbox_fn_item_height_t fn_height, listbox_fn_item_height_t fn_height,
@ -60,21 +63,6 @@ void listbox_delete(struct listbox *lb)
mem_free(lb->ch); 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) void listbox_resize(struct listbox *lb, int y, int x, int h, int w)
{ {
EXIT_IF(lb == NULL, "null pointer"); 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) if (lb->item_sel < 0)
return; return;
listbox_fix_visible_region(lb); listbox_sel_in_view(lb);
} }
void listbox_set_cb_data(struct listbox *lb, void *cb_data) 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; lb->cb_data = cb_data;
} }
static void listbox_fix_sel(struct listbox *, int);
void listbox_load_items(struct listbox *lb, int item_count) void listbox_load_items(struct listbox *lb, int item_count)
{ {
int i, ch; int i, ch;
lb->item_count = item_count; lb->item_count = item_count;
if (item_count == 0) { if (item_count == 0) {
lb->item_sel = -1; lb->item_sel = -1;
return; return;
@ -114,14 +99,13 @@ void listbox_load_items(struct listbox *lb, int item_count)
ch += lb->fn_height(i, lb->cb_data); ch += lb->fn_height(i, lb->cb_data);
} }
lb->ch[item_count] = ch; lb->ch[item_count] = ch;
/* The pad lines: 0,.., ch - 1. */
wins_scrollwin_set_pad(&(lb->sw), ch); wins_scrollwin_set_pad(&(lb->sw), ch);
if (item_count > 0 && lb->item_sel < 0) /* Adjust the selection. */
lb->item_sel = 0;
else if (lb->item_sel >= item_count)
lb->item_sel = item_count - 1;
listbox_fix_sel(lb, 1); listbox_fix_sel(lb, 1);
listbox_fix_visible_region(lb); listbox_sel_in_view(lb);
} }
void listbox_draw_deco(struct listbox *lb, int hilt) void listbox_draw_deco(struct listbox *lb, int hilt)
@ -148,6 +132,7 @@ int listbox_get_sel(struct listbox *lb)
return lb->item_sel; return lb->item_sel;
} }
/* Avoid non-text items. */
static void listbox_fix_sel(struct listbox *lb, int direction) static void listbox_fix_sel(struct listbox *lb, int direction)
{ {
int did_flip = 0; int did_flip = 0;
@ -157,6 +142,11 @@ static void listbox_fix_sel(struct listbox *lb, int direction)
direction = direction > 0 ? 1 : -1; 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) { while (lb->type[lb->item_sel] != LISTBOX_ROW_TEXT) {
if ((direction == -1 && lb->item_sel == 0) || if ((direction == -1 && lb->item_sel == 0) ||
(direction == 1 && lb->item_sel == lb->item_count - 1)) { (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) if (lb->item_sel < 0)
return; return;
listbox_fix_visible_region(lb); listbox_sel_in_view(lb);
} }
void listbox_sel_move(struct listbox *lb, int delta) 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);
}
/* 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) if (lb->item_count == 0)
return; return 0;
lb->item_sel += delta; 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); listbox_fix_sel(lb, delta);
if (lb->item_sel < 0) if (lb->item_sel < 0)
return; return 0;
listbox_fix_visible_region(lb); listbox_sel_in_view(lb);
return lb->item_sel != saved_sel;
} }

View File

@ -415,13 +415,14 @@ void wins_scrollwin_down(struct scrollwin *sw, int amount)
sw->line_off = sw->line_num - inner_h; sw->line_off = sw->line_num - inner_h;
} }
void wins_scrollwin_ensure_visible(struct scrollwin *sw, unsigned line) /* Keep 'line' in the viewport of a scrollwindow. */
void wins_scrollwin_in_view(struct scrollwin *sw, unsigned line)
{ {
int inner_h = sw->h - (conf.compact_panels ? 2 : 4); int inner_h = sw->h - (conf.compact_panels ? 2 : 4);
if (line < sw->line_off) if (line < sw->line_off)
sw->line_off = line; sw->line_off = line;
else if (line >= sw->line_off + inner_h) else if (line > sw->line_off + inner_h - 1)
sw->line_off = line - inner_h + 1; sw->line_off = line - inner_h + 1;
} }