summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/calcurse.h18
-rw-r--r--src/custom.c60
-rw-r--r--src/notify.c21
-rw-r--r--src/utils.c2
-rw-r--r--src/wins.c115
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);
diff --git a/src/wins.c b/src/wins.c
index 3ad7010..da517e8 100644
--- a/src/wins.c
+++ b/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;
-
- 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)