diff options
-rw-r--r-- | src/calcurse.h | 18 | ||||
-rw-r--r-- | src/custom.c | 60 | ||||
-rw-r--r-- | src/notify.c | 21 | ||||
-rw-r--r-- | src/utils.c | 2 | ||||
-rw-r--r-- | src/wins.c | 115 |
5 files changed, 123 insertions, 93 deletions
diff --git a/src/calcurse.h b/src/calcurse.h index 5da79e2..53610c4 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -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 *); diff --git a/src/custom.c b/src/custom.c index 7bcbffc..66081c1 100644 --- a/src/custom.c +++ b/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); } diff --git a/src/notify.c b/src/notify.c index 816da3c..37fec8f 100644 --- a/src/notify.c +++ b/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); diff --git a/src/utils.c b/src/utils.c index a1d410a..493a180 100644 --- a/src/utils.c +++ b/src/utils.c @@ -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); @@ -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; - - 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 ((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); + 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->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; + + 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) |