Add support for caption rows in list boxes
This adds support for rows that cannot be selected. Such rows can be used for section headings and the like. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
a5f3e53ce3
commit
2a15531bb9
@ -511,13 +511,21 @@ struct scrollwin {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Generic list box structure. */
|
/* Generic list box structure. */
|
||||||
|
enum listbox_row_type {
|
||||||
|
LISTBOX_ROW_TEXT,
|
||||||
|
LISTBOX_ROW_CAPTION
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum listbox_row_type (*listbox_fn_item_type_t) (int, void *);
|
||||||
typedef int (*listbox_fn_item_height_t) (int, void *);
|
typedef int (*listbox_fn_item_height_t) (int, void *);
|
||||||
typedef void (*listbox_fn_draw_item_t) (int, WINDOW *, int, int, void *);
|
typedef void (*listbox_fn_draw_item_t) (int, WINDOW *, int, int, void *);
|
||||||
|
|
||||||
struct listbox {
|
struct listbox {
|
||||||
struct scrollwin sw;
|
struct scrollwin sw;
|
||||||
unsigned item_count;
|
unsigned item_count;
|
||||||
unsigned item_sel;
|
int item_sel;
|
||||||
|
listbox_fn_item_type_t fn_type;
|
||||||
|
enum listbox_row_type *type;
|
||||||
listbox_fn_item_height_t fn_height;
|
listbox_fn_item_height_t fn_height;
|
||||||
unsigned *ch;
|
unsigned *ch;
|
||||||
listbox_fn_draw_item_t fn_draw;
|
listbox_fn_draw_item_t fn_draw;
|
||||||
@ -793,7 +801,9 @@ int keys_check_missing_bindings(void);
|
|||||||
void keys_fill_missing(void);
|
void keys_fill_missing(void);
|
||||||
|
|
||||||
/* listbox.c */
|
/* listbox.c */
|
||||||
void listbox_init(struct listbox *, int, int, int, int, const char *, listbox_fn_item_height_t, listbox_fn_draw_item_t);
|
void listbox_init(struct listbox *, int, int, int, int, const char *,
|
||||||
|
listbox_fn_item_type_t, listbox_fn_item_height_t,
|
||||||
|
listbox_fn_draw_item_t);
|
||||||
void listbox_delete(struct listbox *);
|
void listbox_delete(struct listbox *);
|
||||||
void listbox_resize(struct listbox *, int, int, int, int);
|
void listbox_resize(struct listbox *, int, int, int, int);
|
||||||
void listbox_set_cb_data(struct listbox *, void *);
|
void listbox_set_cb_data(struct listbox *, void *);
|
||||||
@ -951,6 +961,7 @@ void ui_day_load_items(void);
|
|||||||
void ui_day_sel_reset(void);
|
void ui_day_sel_reset(void);
|
||||||
void ui_day_sel_move(int);
|
void ui_day_sel_move(int);
|
||||||
void ui_day_draw(int, WINDOW *, int, int, void *);
|
void ui_day_draw(int, WINDOW *, int, int, void *);
|
||||||
|
enum listbox_row_type ui_day_row_type(int, void *);
|
||||||
int ui_day_height(int, void *);
|
int ui_day_height(int, void *);
|
||||||
void ui_day_update_panel(int);
|
void ui_day_update_panel(int);
|
||||||
void ui_day_popup_item(void);
|
void ui_day_popup_item(void);
|
||||||
@ -964,6 +975,7 @@ void ui_todo_delete(void);
|
|||||||
void ui_todo_edit(void);
|
void ui_todo_edit(void);
|
||||||
void ui_todo_pipe(void);
|
void ui_todo_pipe(void);
|
||||||
void ui_todo_draw(int, WINDOW *, int, int, void *);
|
void ui_todo_draw(int, WINDOW *, int, int, void *);
|
||||||
|
enum listbox_row_type ui_todo_row_type(int, void *);
|
||||||
int ui_todo_height(int, void *);
|
int ui_todo_height(int, void *);
|
||||||
void ui_todo_load_items(void);
|
void ui_todo_load_items(void);
|
||||||
void ui_todo_sel_move(int);
|
void ui_todo_sel_move(int);
|
||||||
|
@ -684,6 +684,11 @@ static void print_general_option(int i, WINDOW *win, int y, int hilt, void *cb_d
|
|||||||
custom_remove_attr(win, ATTR_HIGHEST);
|
custom_remove_attr(win, ATTR_HIGHEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum listbox_row_type general_option_row_type(int i, void *cb_data)
|
||||||
|
{
|
||||||
|
return LISTBOX_ROW_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
static int general_option_height(int i, void *cb_data)
|
static int general_option_height(int i, void *cb_data)
|
||||||
{
|
{
|
||||||
if (i == 9)
|
if (i == 9)
|
||||||
@ -771,8 +776,8 @@ void custom_general_config(void)
|
|||||||
|
|
||||||
clear();
|
clear();
|
||||||
listbox_init(&lb, 0, 0, notify_bar() ? row - 3 : row - 2, col,
|
listbox_init(&lb, 0, 0, notify_bar() ? row - 3 : row - 2, col,
|
||||||
_("general options"), general_option_height,
|
_("general options"), general_option_row_type,
|
||||||
print_general_option);
|
general_option_height, print_general_option);
|
||||||
listbox_load_items(&lb, 10);
|
listbox_load_items(&lb, 10);
|
||||||
listbox_draw_deco(&lb, 0);
|
listbox_draw_deco(&lb, 0);
|
||||||
status_mesg("", "");
|
status_mesg("", "");
|
||||||
|
@ -37,12 +37,15 @@
|
|||||||
#include "calcurse.h"
|
#include "calcurse.h"
|
||||||
|
|
||||||
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_height_t fn_height,
|
const char *label, listbox_fn_item_type_t fn_type,
|
||||||
|
listbox_fn_item_height_t fn_height,
|
||||||
listbox_fn_draw_item_t fn_draw)
|
listbox_fn_draw_item_t fn_draw)
|
||||||
{
|
{
|
||||||
EXIT_IF(lb == NULL, "null pointer");
|
EXIT_IF(lb == NULL, "null pointer");
|
||||||
wins_scrollwin_init(&(lb->sw), y, x, h, w, label);
|
wins_scrollwin_init(&(lb->sw), y, x, h, w, label);
|
||||||
lb->item_count = lb->item_sel = 0;
|
lb->item_count = lb->item_sel = 0;
|
||||||
|
lb->fn_type = fn_type;
|
||||||
|
lb->type = NULL;
|
||||||
lb->fn_height = fn_height;
|
lb->fn_height = fn_height;
|
||||||
lb->ch = NULL;
|
lb->ch = NULL;
|
||||||
lb->fn_draw = fn_draw;
|
lb->fn_draw = fn_draw;
|
||||||
@ -53,6 +56,7 @@ void listbox_delete(struct listbox *lb)
|
|||||||
{
|
{
|
||||||
EXIT_IF(lb == NULL, "null pointer");
|
EXIT_IF(lb == NULL, "null pointer");
|
||||||
wins_scrollwin_delete(&(lb->sw));
|
wins_scrollwin_delete(&(lb->sw));
|
||||||
|
free(lb->type);
|
||||||
free(lb->ch);
|
free(lb->ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +82,15 @@ void listbox_load_items(struct listbox *lb, int item_count)
|
|||||||
if (lb->item_sel >= item_count)
|
if (lb->item_sel >= item_count)
|
||||||
lb->item_sel = item_count - 1;
|
lb->item_sel = item_count - 1;
|
||||||
|
|
||||||
|
if (item_count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(lb->type);
|
||||||
free(lb->ch);
|
free(lb->ch);
|
||||||
|
lb->type = xmalloc(item_count * sizeof(unsigned));
|
||||||
lb->ch = xmalloc((item_count + 1) * sizeof(unsigned));
|
lb->ch = xmalloc((item_count + 1) * sizeof(unsigned));
|
||||||
for (i = 0, ch = 0; i < item_count; i++) {
|
for (i = 0, ch = 0; i < item_count; i++) {
|
||||||
|
lb->type[i] = lb->fn_type(i, lb->cb_data);
|
||||||
lb->ch[i] = ch;
|
lb->ch[i] = ch;
|
||||||
ch += lb->fn_height(i, lb->cb_data);
|
ch += lb->fn_height(i, lb->cb_data);
|
||||||
}
|
}
|
||||||
@ -113,12 +123,53 @@ int listbox_get_sel(struct listbox *lb)
|
|||||||
return lb->item_sel;
|
return lb->item_sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void listbox_set_sel(struct listbox *lb, unsigned pos)
|
static void listbox_fix_sel(struct listbox *lb, int direction)
|
||||||
{
|
{
|
||||||
lb->item_sel = pos;
|
int did_flip = 0;
|
||||||
|
|
||||||
|
if (lb->item_count == 0 || direction == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
direction = direction > 0 ? 1 : -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)) {
|
||||||
|
if (did_flip) {
|
||||||
|
lb->item_sel = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
direction = -direction;
|
||||||
|
did_flip = 1;
|
||||||
|
} else {
|
||||||
|
lb->item_sel += direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[lb->item_sel + 1] - 1);
|
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_set_sel(struct listbox *lb, unsigned pos)
|
||||||
|
{
|
||||||
|
lb->item_sel = pos;
|
||||||
|
listbox_fix_sel(lb, 1);
|
||||||
|
if (lb->item_sel < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
listbox_fix_visible_region(lb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void listbox_sel_move(struct listbox *lb, int delta)
|
void listbox_sel_move(struct listbox *lb, int delta)
|
||||||
@ -126,13 +177,15 @@ void listbox_sel_move(struct listbox *lb, int delta)
|
|||||||
if (lb->item_count == 0)
|
if (lb->item_count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (delta < 0 && lb->item_sel < -delta)
|
lb->item_sel += delta;
|
||||||
|
if (lb->item_sel < 0)
|
||||||
lb->item_sel = 0;
|
lb->item_sel = 0;
|
||||||
else if (delta > 0 && lb->item_sel + delta >= lb->item_count)
|
else if (lb->item_sel >= lb->item_count)
|
||||||
lb->item_sel = lb->item_count - 1;
|
lb->item_sel = lb->item_count - 1;
|
||||||
else
|
|
||||||
lb->item_sel += delta;
|
|
||||||
|
|
||||||
wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[lb->item_sel]);
|
listbox_fix_sel(lb, delta);
|
||||||
wins_scrollwin_ensure_visible(&(lb->sw), lb->ch[lb->item_sel + 1] - 1);
|
if (lb->item_sel < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
listbox_fix_visible_region(lb);
|
||||||
}
|
}
|
||||||
|
@ -658,6 +658,11 @@ static void print_config_option(int i, WINDOW *win, int y, int hilt, void *cb_da
|
|||||||
custom_remove_attr(win, ATTR_HIGHEST);
|
custom_remove_attr(win, ATTR_HIGHEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum listbox_row_type config_option_row_type(int i, void *cb_data)
|
||||||
|
{
|
||||||
|
return LISTBOX_ROW_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
static int config_option_height(int i, void *cb_data)
|
static int config_option_height(int i, void *cb_data)
|
||||||
{
|
{
|
||||||
return 3;
|
return 3;
|
||||||
@ -761,7 +766,9 @@ void notify_config_bar(void)
|
|||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
listbox_init(&lb, 0, 0, notify_bar() ? row - 3 : row - 2, col, _("notification options"), config_option_height, print_config_option);
|
listbox_init(&lb, 0, 0, notify_bar() ? row - 3 : row - 2, col,
|
||||||
|
_("notification options"), config_option_row_type,
|
||||||
|
config_option_height, print_config_option);
|
||||||
listbox_load_items(&lb, 8);
|
listbox_load_items(&lb, 8);
|
||||||
listbox_draw_deco(&lb, 0);
|
listbox_draw_deco(&lb, 0);
|
||||||
status_mesg("", "");
|
status_mesg("", "");
|
||||||
|
@ -843,6 +843,11 @@ void ui_day_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum listbox_row_type ui_day_row_type(int i, void *cb_data)
|
||||||
|
{
|
||||||
|
return LISTBOX_ROW_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
int ui_day_height(int n, void *cb_data)
|
int ui_day_height(int n, void *cb_data)
|
||||||
{
|
{
|
||||||
struct day_item *item = day_get_item(n);
|
struct day_item *item = day_get_item(n);
|
||||||
|
@ -177,6 +177,11 @@ void ui_todo_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
|
|||||||
*((llist_item_t **)cb_data) = i->next;
|
*((llist_item_t **)cb_data) = i->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum listbox_row_type ui_todo_row_type(int i, void *cb_data)
|
||||||
|
{
|
||||||
|
return LISTBOX_ROW_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
int ui_todo_height(int n, void *cb_data)
|
int ui_todo_height(int n, void *cb_data)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -250,11 +250,13 @@ static void wins_init_panels(void)
|
|||||||
wins_sbar_width(), _("Calendar"));
|
wins_sbar_width(), _("Calendar"));
|
||||||
|
|
||||||
listbox_init(&lb_apt, win[APP].y, win[APP].x, win[APP].h, win[APP].w,
|
listbox_init(&lb_apt, win[APP].y, win[APP].x, win[APP].h, win[APP].w,
|
||||||
_("Appointments"), ui_day_height, ui_day_draw);
|
_("Appointments"), ui_day_row_type, ui_day_height,
|
||||||
|
ui_day_draw);
|
||||||
ui_day_load_items();
|
ui_day_load_items();
|
||||||
|
|
||||||
listbox_init(&lb_todo, win[TOD].y, win[TOD].x, win[TOD].h, win[TOD].w,
|
listbox_init(&lb_todo, win[TOD].y, win[TOD].x, win[TOD].h, win[TOD].w,
|
||||||
_("TODO"), ui_todo_height, ui_todo_draw);
|
_("TODO"), ui_todo_row_type, ui_todo_height,
|
||||||
|
ui_todo_draw);
|
||||||
ui_todo_load_items();
|
ui_todo_load_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user