diff options
Diffstat (limited to 'src/interface-curses/curses-info-popup.c')
-rw-r--r-- | src/interface-curses/curses-info-popup.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/src/interface-curses/curses-info-popup.c b/src/interface-curses/curses-info-popup.c index e6e1549..dffbcf8 100644 --- a/src/interface-curses/curses-info-popup.c +++ b/src/interface-curses/curses-info-popup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2024 Robin Haberkorn + * Copyright (C) 2012-2025 Robin Haberkorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -200,6 +200,65 @@ teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr) wmove(ctx->window, bar_y, cols-1); wattron(ctx->window, A_REVERSE); wvline(ctx->window, ' ', bar_height); +} + +/** + * Find the entry at the given character coordinates. + * + * @param ctx The popup widget to look up + * @param y The pointer's Y position, relative to the popup's window + * @param x The pointer's X position, relative to the popup's window + * @return Pointer to the entry's string under the pointer or NULL. + * This string is owned by the popup and is only valid until the + * popup is cleared. + * + * @note This must match the calculations in teco_curses_info_popup_init_pad(). + * But we could perhaps also cache these values. + */ +const teco_string_t * +teco_curses_info_popup_getentry(teco_curses_info_popup_t *ctx, gint y, gint x) +{ + int cols = getmaxx(stdscr); /**! screen width */ + gint pad_cols; /**! entry columns */ + gint pad_colwidth; /**! width per entry column */ + + if (y == 0) + return NULL; + + /* + * With Unicode icons enabled, we reserve 2 characters at the beginning and one + * after the filename/directory. + * Otherwise 2 characters after the entry. + */ + gint reserve = teco_ed & TECO_ED_ICONS ? 2+1 : 2; + pad_colwidth = MIN(ctx->longest + reserve, cols - 2); + + /* pad_cols = floor((cols - 2) / pad_colwidth) */ + pad_cols = (cols - 2) / pad_colwidth; + + gint cur_col = 0; + for (teco_stailq_entry_t *cur = ctx->list.first; cur != NULL; cur = cur->next) { + teco_popup_entry_t *entry = (teco_popup_entry_t *)cur; + gint cur_line = cur_col/pad_cols + 1; + + if (cur_line > ctx->pad_first_line+y) + break; + if (cur_line == ctx->pad_first_line+y && + x > (cur_col % pad_cols)*pad_colwidth && x <= ((cur_col % pad_cols)+1)*pad_colwidth) + return &entry->name; + + cur_col++; + } + + return NULL; +} + +void +teco_curses_info_popup_scroll_page(teco_curses_info_popup_t *ctx) +{ + gint lines = getmaxy(stdscr); + gint pad_lines = getmaxy(ctx->pad); + gint popup_lines = MIN(pad_lines + 1, lines - 1); /* progress scroll position */ ctx->pad_first_line += popup_lines - 1; @@ -211,6 +270,19 @@ teco_curses_info_popup_show(teco_curses_info_popup_t *ctx, attr_t attr) } void +teco_curses_info_popup_scroll(teco_curses_info_popup_t *ctx, gint delta) +{ + gint lines = getmaxy(stdscr); + gint pad_lines = getmaxy(ctx->pad); + gint popup_lines = MIN(pad_lines + 1, lines - 1); + + ctx->pad_first_line = MAX(ctx->pad_first_line+delta, 0); + if (pad_lines - ctx->pad_first_line < popup_lines - 1) + /* show last page */ + ctx->pad_first_line = pad_lines - (popup_lines - 1); +} + +void teco_curses_info_popup_clear(teco_curses_info_popup_t *ctx) { if (ctx->window) |