summaryrefslogtreecommitdiff
path: root/src/wins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wins.c')
-rw-r--r--src/wins.c115
1 files changed, 84 insertions, 31 deletions
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)