Rework scroll window implementation
This complete rewrite of the scroll window implementation decouples scroll windows from every other window abstraction layer we use. Note that this leads to some code duplication. The long-term purpose of this rewrite, however, is to eventually make every panel use scroll windows. This makes for a huge cleanup of the UI code. Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
parent
ca83e65696
commit
7184da0fa3
@ -504,10 +504,14 @@ struct window {
|
||||
|
||||
/* Generic scrolling window structure. */
|
||||
struct scrollwin {
|
||||
struct window win;
|
||||
struct window pad;
|
||||
unsigned first_visible_line;
|
||||
unsigned total_lines;
|
||||
WINDOW *win;
|
||||
WINDOW *inner;
|
||||
int y;
|
||||
int x;
|
||||
int h;
|
||||
int w;
|
||||
unsigned line_off;
|
||||
unsigned line_num;
|
||||
const char *label;
|
||||
};
|
||||
|
||||
@ -1047,11 +1051,15 @@ enum win wins_slctd(void);
|
||||
void wins_slctd_set(enum win);
|
||||
void wins_slctd_next(void);
|
||||
void wins_init(void);
|
||||
void wins_scrollwin_init(struct scrollwin *);
|
||||
void wins_scrollwin_init(struct scrollwin *, int, int, int, int, const char *);
|
||||
void wins_scrollwin_resize(struct scrollwin *, int, int, int, int);
|
||||
void wins_scrollwin_set_linecount(struct scrollwin *, unsigned);
|
||||
void wins_scrollwin_delete(struct scrollwin *);
|
||||
void wins_scrollwin_draw_deco(struct scrollwin *);
|
||||
void wins_scrollwin_display(struct scrollwin *);
|
||||
void wins_scrollwin_up(struct scrollwin *, int);
|
||||
void wins_scrollwin_down(struct scrollwin *, int);
|
||||
void wins_scrollwin_ensure_visible(struct scrollwin *, unsigned);
|
||||
void wins_reinit(void);
|
||||
void wins_reinit_panels(void);
|
||||
void wins_show(WINDOW *, const char *);
|
||||
|
60
src/custom.c
60
src/custom.c
@ -679,19 +679,6 @@ static int print_general_options(WINDOW * win)
|
||||
return y + YOFF;
|
||||
}
|
||||
|
||||
void custom_set_swsiz(struct scrollwin *sw)
|
||||
{
|
||||
sw->win.x = 0;
|
||||
sw->win.y = 0;
|
||||
sw->win.h = (notify_bar())? row - 3 : row - 2;
|
||||
sw->win.w = col;
|
||||
|
||||
sw->pad.x = 1;
|
||||
sw->pad.y = 3;
|
||||
sw->pad.h = BUFSIZ;
|
||||
sw->pad.w = col - 2 * sw->pad.x - 1;
|
||||
}
|
||||
|
||||
/* General configuration. */
|
||||
void custom_general_config(void)
|
||||
{
|
||||
@ -710,12 +697,10 @@ void custom_general_config(void)
|
||||
char *buf;
|
||||
|
||||
clear();
|
||||
custom_set_swsiz(&cwin);
|
||||
cwin.label = _("general options");
|
||||
wins_scrollwin_init(&cwin);
|
||||
wins_show(cwin.win.p, cwin.label);
|
||||
wins_scrollwin_init(&cwin, 0, 0, notify_bar() ? row - 3 : row - 2, col, _("general options"));
|
||||
wins_scrollwin_draw_deco(&cwin);
|
||||
status_mesg(number_str, keys);
|
||||
cwin.total_lines = print_general_options(cwin.pad.p);
|
||||
wins_scrollwin_set_linecount(&cwin, print_general_options(cwin.inner));
|
||||
wins_scrollwin_display(&cwin);
|
||||
|
||||
buf = mem_malloc(BUFSIZ);
|
||||
@ -785,15 +770,10 @@ void custom_general_config(void)
|
||||
if (resize) {
|
||||
resize = 0;
|
||||
wins_reset();
|
||||
wins_scrollwin_delete(&cwin);
|
||||
custom_set_swsiz(&cwin);
|
||||
wins_scrollwin_init(&cwin);
|
||||
wins_show(cwin.win.p, cwin.label);
|
||||
cwin.first_visible_line = 0;
|
||||
wins_scrollwin_resize(&cwin, 0, 0, notify_bar() ? row - 3 : row - 2, col);
|
||||
wins_scrollwin_draw_deco(&cwin);
|
||||
delwin(win[STA].p);
|
||||
win[STA].p =
|
||||
newwin(win[STA].h, win[STA].w, win[STA].y,
|
||||
win[STA].x);
|
||||
win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
|
||||
keypad(win[STA].p, TRUE);
|
||||
if (notify_bar()) {
|
||||
notify_reinit_bar();
|
||||
@ -802,9 +782,10 @@ void custom_general_config(void)
|
||||
}
|
||||
|
||||
status_mesg(number_str, keys);
|
||||
cwin.total_lines = print_general_options(cwin.pad.p);
|
||||
print_general_options(cwin.inner);
|
||||
wins_scrollwin_display(&cwin);
|
||||
}
|
||||
|
||||
mem_free(buf);
|
||||
wins_scrollwin_delete(&cwin);
|
||||
}
|
||||
@ -904,16 +885,13 @@ void custom_keys_config(void)
|
||||
const int LABELLINES = 3;
|
||||
|
||||
clear();
|
||||
custom_set_swsiz(&kwin);
|
||||
nbdisplayed = (kwin.win.h - LABELLINES) / LINESPERKEY;
|
||||
kwin.label = _("keys configuration");
|
||||
wins_scrollwin_init(&kwin);
|
||||
wins_show(kwin.win.p, kwin.label);
|
||||
nbdisplayed = ((notify_bar() ? row - 3 : row - 2) - LABELLINES) / LINESPERKEY;
|
||||
wins_scrollwin_init(&kwin, 0, 0, notify_bar() ? row - 3 : row - 2, col, _("keys configuration"));
|
||||
wins_scrollwin_set_linecount(&kwin, NBKEYS * LINESPERKEY);
|
||||
wins_scrollwin_draw_deco(&kwin);
|
||||
custom_keys_config_bar();
|
||||
selrow = selelm = 0;
|
||||
nbrowelm =
|
||||
print_keys_bindings(kwin.pad.p, selrow, selelm, LINESPERKEY);
|
||||
kwin.total_lines = NBKEYS * LINESPERKEY;
|
||||
nbrowelm = print_keys_bindings(kwin.inner, selrow, selelm, LINESPERKEY);
|
||||
wins_scrollwin_display(&kwin);
|
||||
firstrow = 0;
|
||||
lastrow = firstrow + nbdisplayed - 1;
|
||||
@ -976,9 +954,9 @@ void custom_keys_config(void)
|
||||
not_recognized = 1;
|
||||
WARN_MSG(_("This key is not yet recognized by calcurse, "
|
||||
"please choose another one."));
|
||||
werase(kwin.pad.p);
|
||||
werase(kwin.inner);
|
||||
nbrowelm =
|
||||
print_keys_bindings(kwin.pad.p,
|
||||
print_keys_bindings(kwin.inner,
|
||||
selrow,
|
||||
selelm,
|
||||
LINESPERKEY);
|
||||
@ -1002,9 +980,9 @@ void custom_keys_config(void)
|
||||
WARN_MSG(_("This key is already in use for %s, "
|
||||
"please choose another one."),
|
||||
keys_get_label(action));
|
||||
werase(kwin.pad.p);
|
||||
werase(kwin.inner);
|
||||
nbrowelm =
|
||||
print_keys_bindings(kwin.pad.p,
|
||||
print_keys_bindings(kwin.inner,
|
||||
selrow,
|
||||
selelm,
|
||||
LINESPERKEY);
|
||||
@ -1036,9 +1014,9 @@ void custom_keys_config(void)
|
||||
return;
|
||||
}
|
||||
custom_keys_config_bar();
|
||||
werase(kwin.pad.p);
|
||||
werase(kwin.inner);
|
||||
nbrowelm =
|
||||
print_keys_bindings(kwin.pad.p, selrow, selelm,
|
||||
print_keys_bindings(kwin.inner, selrow, selelm,
|
||||
LINESPERKEY);
|
||||
wins_scrollwin_display(&kwin);
|
||||
}
|
||||
|
21
src/notify.c
21
src/notify.c
@ -668,14 +668,8 @@ static unsigned print_config_options(WINDOW * optwin)
|
||||
|
||||
static void reinit_conf_win(struct scrollwin *win)
|
||||
{
|
||||
unsigned first_line;
|
||||
|
||||
first_line = win->first_visible_line;
|
||||
wins_scrollwin_delete(win);
|
||||
custom_set_swsiz(win);
|
||||
wins_scrollwin_init(win);
|
||||
wins_show(win->win.p, win->label);
|
||||
win->first_visible_line = first_line;
|
||||
wins_scrollwin_resize(win, 0, 0, notify_bar() ? row - 3 : row - 2, col);
|
||||
wins_scrollwin_draw_deco(win);
|
||||
}
|
||||
|
||||
/* Notify-bar configuration. */
|
||||
@ -697,12 +691,10 @@ void notify_config_bar(void)
|
||||
int ch;
|
||||
|
||||
clear();
|
||||
custom_set_swsiz(&cwin);
|
||||
cwin.label = _("notification options");
|
||||
wins_scrollwin_init(&cwin);
|
||||
wins_show(cwin.win.p, cwin.label);
|
||||
wins_scrollwin_init(&cwin, 0, 0, notify_bar() ? row - 3 : row - 2, col, _("notification options"));
|
||||
wins_scrollwin_draw_deco(&cwin);
|
||||
status_mesg(number_str, keys);
|
||||
cwin.total_lines = print_config_options(cwin.pad.p);
|
||||
wins_scrollwin_set_linecount(&cwin, print_config_options(cwin.inner));
|
||||
wins_scrollwin_display(&cwin);
|
||||
|
||||
buf = mem_malloc(BUFSIZ);
|
||||
@ -724,7 +716,6 @@ void notify_config_bar(void)
|
||||
notify_start_main_thread();
|
||||
else
|
||||
notify_stop_main_thread();
|
||||
wins_scrollwin_delete(&cwin);
|
||||
reinit_conf_win(&cwin);
|
||||
break;
|
||||
case '2':
|
||||
@ -809,7 +800,7 @@ void notify_config_bar(void)
|
||||
}
|
||||
|
||||
status_mesg(number_str, keys);
|
||||
cwin.total_lines = print_config_options(cwin.pad.p);
|
||||
print_config_options(cwin.inner);
|
||||
wins_scrollwin_display(&cwin);
|
||||
}
|
||||
mem_free(buf);
|
||||
|
@ -499,7 +499,7 @@ void
|
||||
draw_scrollbar(WINDOW * win, int y, int x, int length,
|
||||
int bar_top, int bar_bottom, unsigned hilt)
|
||||
{
|
||||
mvwvline(win, bar_top, x, ACS_VLINE, bar_bottom - bar_top);
|
||||
mvwvline(win, bar_top, x, ACS_VLINE, bar_bottom - bar_top + 1);
|
||||
if (hilt)
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
wattron(win, A_REVERSE);
|
||||
|
111
src/wins.c
111
src/wins.c
@ -281,61 +281,114 @@ void wins_init(void)
|
||||
* Create a new window and its associated pad, which is used to make the
|
||||
* scrolling faster.
|
||||
*/
|
||||
void wins_scrollwin_init(struct scrollwin *sw)
|
||||
void wins_scrollwin_init(struct scrollwin *sw, int y, int x, int h, int w, const char *label)
|
||||
{
|
||||
EXIT_IF(sw == NULL, "null pointer");
|
||||
sw->win.p = newwin(sw->win.h, sw->win.w, sw->win.y, sw->win.x);
|
||||
sw->pad.p = newpad(sw->pad.h, sw->pad.w);
|
||||
sw->first_visible_line = 0;
|
||||
sw->total_lines = 0;
|
||||
sw->y = y;
|
||||
sw->x = x;
|
||||
sw->h = h;
|
||||
sw->w = w;
|
||||
sw->win = newwin(h, w, y, x);
|
||||
sw->inner = newpad(BUFSIZ, w);
|
||||
sw->line_num = sw->line_off = 0;
|
||||
sw->label = label;
|
||||
}
|
||||
|
||||
/* Resize a scrolling window. */
|
||||
void wins_scrollwin_resize(struct scrollwin *sw, int y, int x, int h, int w)
|
||||
{
|
||||
EXIT_IF(sw == NULL, "null pointer");
|
||||
sw->y = y;
|
||||
sw->x = x;
|
||||
sw->h = h;
|
||||
sw->w = w;
|
||||
delwin(sw->inner);
|
||||
delwin(sw->win);
|
||||
sw->win = newwin(h, w, y, x);
|
||||
sw->inner = newpad(BUFSIZ, w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the number of lines to be displayed.
|
||||
*/
|
||||
void wins_scrollwin_set_linecount(struct scrollwin *sw, unsigned lines)
|
||||
{
|
||||
sw->line_num = lines;
|
||||
}
|
||||
|
||||
/* Free an already created scrollwin. */
|
||||
void wins_scrollwin_delete(struct scrollwin *sw)
|
||||
{
|
||||
EXIT_IF(sw == NULL, "null pointer");
|
||||
delwin(sw->win.p);
|
||||
delwin(sw->pad.p);
|
||||
delwin(sw->inner);
|
||||
delwin(sw->win);
|
||||
}
|
||||
|
||||
/* Draw window border and label. */
|
||||
void wins_scrollwin_draw_deco(struct scrollwin *sw)
|
||||
{
|
||||
box(sw->win, 0, 0);
|
||||
|
||||
if (!conf.compact_panels) {
|
||||
mvwaddch(sw->win, 2, 0, ACS_LTEE);
|
||||
mvwhline(sw->win, 2, 1, ACS_HLINE, sw->w - 2);
|
||||
mvwaddch(sw->win, 2, sw->w - 1, ACS_RTEE);
|
||||
|
||||
print_in_middle(sw->win, 1, 0, sw->w, sw->label);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a scrolling window. */
|
||||
void wins_scrollwin_display(struct scrollwin *sw)
|
||||
{
|
||||
const int visible_lines = sw->win.h - sw->pad.y - 1;
|
||||
int inner_y = (conf.compact_panels ? 1 : 3);
|
||||
int inner_x = 1;
|
||||
int inner_h = sw->h - (conf.compact_panels ? 2 : 4);
|
||||
int inner_w = sw->w - 2;
|
||||
|
||||
if (sw->total_lines > visible_lines) {
|
||||
int sbar_length =
|
||||
visible_lines * visible_lines / sw->total_lines;
|
||||
int highend =
|
||||
visible_lines * sw->first_visible_line /
|
||||
sw->total_lines;
|
||||
int sbar_top = highend + sw->pad.y + 1;
|
||||
if (sw->line_num > inner_h) {
|
||||
int sbar_h = MAX(inner_h * inner_h / sw->line_num, 1);
|
||||
int sbar_y = inner_y + sw->line_off * (inner_h - sbar_h) / (sw->line_num - inner_h);
|
||||
int sbar_x = sw->w - 1;
|
||||
|
||||
if ((sbar_top + sbar_length) > sw->win.h - 1)
|
||||
sbar_length = sw->win.h - sbar_top;
|
||||
draw_scrollbar(sw->win.p, sbar_top,
|
||||
sw->win.w + sw->win.x - 2, sbar_length,
|
||||
sw->pad.y + 1, sw->win.h - 1, 1);
|
||||
draw_scrollbar(sw->win, sbar_y, sbar_x, sbar_h, inner_y,
|
||||
inner_y + inner_h - 1, 1);
|
||||
}
|
||||
|
||||
wmove(win[STA].p, 0, 0);
|
||||
wnoutrefresh(sw->win.p);
|
||||
pnoutrefresh(sw->pad.p, sw->first_visible_line, 0, sw->pad.y,
|
||||
sw->pad.x, sw->win.h - sw->pad.y + 1,
|
||||
sw->win.w - sw->win.x);
|
||||
wnoutrefresh(sw->win);
|
||||
pnoutrefresh(sw->inner, sw->line_off, 0, sw->y + inner_y,
|
||||
sw->x + inner_x, sw->y + inner_y + inner_h - 1,
|
||||
sw->x + inner_x + inner_w - 1);
|
||||
wins_doupdate();
|
||||
}
|
||||
|
||||
void wins_scrollwin_up(struct scrollwin *sw, int amount)
|
||||
{
|
||||
if (sw->first_visible_line > 0)
|
||||
sw->first_visible_line -= amount;
|
||||
if ((int)sw->line_off - amount > 0)
|
||||
sw->line_off -= amount;
|
||||
else
|
||||
sw->line_off = 0;
|
||||
}
|
||||
|
||||
void wins_scrollwin_down(struct scrollwin *sw, int amount)
|
||||
{
|
||||
if (sw->total_lines >
|
||||
(sw->first_visible_line + sw->win.h - sw->pad.y - 1))
|
||||
sw->first_visible_line += amount;
|
||||
int inner_h = sw->h - (conf.compact_panels ? 2 : 4);
|
||||
|
||||
sw->line_off += amount;
|
||||
|
||||
if ((int)sw->line_off > (int)sw->line_num - inner_h)
|
||||
sw->line_off = sw->line_num - inner_h;
|
||||
}
|
||||
|
||||
void wins_scrollwin_ensure_visible(struct scrollwin *sw, unsigned line)
|
||||
{
|
||||
int inner_h = sw->h - (conf.compact_panels ? 2 : 4);
|
||||
|
||||
if (line < sw->line_off)
|
||||
sw->line_off = line;
|
||||
else if (line >= sw->line_off + inner_h)
|
||||
sw->line_off = line - inner_h + 1;
|
||||
}
|
||||
|
||||
void wins_reinit_panels(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user