Add Match/Page Counter(Addresses #204) (#325)

* counter with total item count

* filtered item counter

* optimized display code

* refactored overcomplicated code

* fixed warnings that failed Ubuntu test

* fixed inconsistent state

* CLI option for counter

* fixed vertical mode counter
This commit is contained in:
Lucas Merritt 2022-12-27 01:13:59 -07:00 committed by GitHub
parent a1374d487e
commit 77000a680c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 5 deletions

View File

@ -183,6 +183,7 @@ usage(FILE *out, const char *name)
" -K, --no-keyboard ignore keyboard events.\n"
" --binding use alternative key bindings. Available options: vim\n"
" --scrollbar display scrollbar. (none (default), always, autohide)\n"
" --counter display a matched/total items counter. (none (default), always)\n"
" --accept-single immediately return if there is only one item.\n"
" --ifne only display menu if there are items.\n"
" --fork always fork. (bemenu-run)\n"
@ -271,6 +272,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
{ "prefix", required_argument, 0, 'P' },
{ "password", no_argument, 0, 'x' },
{ "scrollbar", required_argument, 0, 0x100 },
{ "counter", required_argument, 0, 0x10a },
{ "accept-single",no_argument, 0, 0x11a },
{ "ifne", no_argument, 0, 0x117 },
{ "fork", no_argument, 0, 0x118 },
@ -362,6 +364,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
case 0x100:
client->scrollbar = (!strcmp(optarg, "none") ? BM_SCROLLBAR_NONE : (!strcmp(optarg, "always") ? BM_SCROLLBAR_ALWAYS : (!strcmp(optarg, "autohide") ? BM_SCROLLBAR_AUTOHIDE : BM_SCROLLBAR_NONE)));
break;
case 0x10a:
client->counter = (!strcmp(optarg, "always"));
break;
case 0x11a:
client->accept_single = true;
break;
@ -543,6 +548,7 @@ menu_with_options(struct client *client)
bm_menu_set_monitor(menu, client->monitor);
bm_menu_set_monitor_name(menu, client->monitor_name);
bm_menu_set_scrollbar(menu, client->scrollbar);
bm_menu_set_counter(menu, client->counter);
bm_menu_set_panel_overlap(menu, !client->no_overlap);
bm_menu_set_spacing(menu, !client->no_spacing);
bm_menu_set_password(menu, client->password);

View File

@ -27,6 +27,7 @@ struct client {
bool center;
bool grab;
bool wrap;
bool counter;
bool accept_single;
bool ifne;
bool no_overlap;

View File

@ -662,7 +662,6 @@ BM_PUBLIC void bm_menu_set_border_radius(struct bm_menu* menu, uint32_t border_r
BM_PUBLIC uint32_t bm_menu_get_border_radius(struct bm_menu* menu);
/**
* Set a hexadecimal color for element.
*
@ -698,6 +697,24 @@ BM_PUBLIC void bm_menu_set_scrollbar(struct bm_menu *menu, enum bm_scrollbar_mod
*/
BM_PUBLIC enum bm_scrollbar_mode bm_menu_get_scrollbar(struct bm_menu *menu);
/**
* Set the counter display mode.
*
* @param menu bm_menu to set the counter for.
* @param display mode to be set.
*/
BM_PUBLIC void bm_menu_set_counter(struct bm_menu *menu, bool mode);
/**
* Get the counter display mode.
*
* @param menu bm_menu to get the counter from.
* @return current counter display mode
*/
BM_PUBLIC bool bm_menu_get_counter(struct bm_menu *menu);
/**
* Set the vertical alignment of the bar.
*

View File

@ -357,6 +357,11 @@ struct bm_menu {
*/
enum bm_scrollbar_mode scrollbar;
/**
* Current counter display mode.
*/
bool counter;
/**
* Should selection be wrapped?
*/

View File

@ -446,6 +446,18 @@ bm_menu_get_scrollbar(struct bm_menu *menu)
return menu->scrollbar;
}
void
bm_menu_set_counter(struct bm_menu *menu, bool mode)
{
menu->counter = mode;
}
bool
bm_menu_get_counter(struct bm_menu *menu)
{
return menu->counter;
}
void
bm_menu_set_align(struct bm_menu *menu, enum bm_align align)
{
@ -778,7 +790,6 @@ bm_menu_filter(struct bm_menu *menu)
size_t oldLen = strlen(menu->old_filter);
addition = (oldLen < len && !memcmp(menu->old_filter, menu->filter, oldLen));
}
if (menu->old_filter && addition && menu->filtered.count <= 0)
return;

View File

@ -296,6 +296,9 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
uint32_t border_radius = menu->border_radius;
uint32_t total_item_count = menu->items.count;
uint32_t filtered_item_count = (menu->filter ? menu->filtered.count : total_item_count);
cairo_set_source_rgba(cairo->cr, 0, 0, 0, 0);
cairo_rectangle(cairo->cr, 0, 0, width, height);
@ -469,15 +472,24 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
out_result->displayed += (cl < width);
out_result->height = fmax(out_result->height, result.height);
}
bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg);
bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg);
if (menu->wrap || menu->index + 1 < count) {
bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg);
bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg);
bm_pango_get_text_extents(cairo, &paint, &result, ">");
paint.pos = (struct pos){ width/cairo->scale - result.x_advance - 2, vpadding + border_size };
paint.box = (struct box){ 1, 2, vpadding, -vpadding, 0, height };
bm_cairo_draw_line(cairo, &paint, &result, ">");
}
}
if (menu->counter) {
char counter[128];
snprintf(counter, sizeof(counter), "[%u/%u]", filtered_item_count, total_item_count);
bm_pango_get_text_extents(cairo, &paint, &result, "%s", counter);
paint.pos = (struct pos){ width/cairo->scale - result.x_advance - 10, vpadding + border_size };
paint.box = (struct box){ 1, 2, vpadding, -vpadding, 0, height };
bm_cairo_draw_line(cairo, &paint, &result, "%s", counter);
}
// Draw borders