mirror of
https://github.com/Cloudef/bemenu
synced 2025-02-19 08:16:49 +00:00
bemenu: add --line-height / -H option
Text is displayed vertically centered in a line. If unspecified, or 0, the previous behaviour of making the height the size of the text, plus two pixels on either side, is used, so there will be no change in behaviour if this option is not used. Fixes https://github.com/Cloudef/bemenu/issues/44.
This commit is contained in:
parent
121367b940
commit
93cde4831b
@ -86,6 +86,7 @@ usage(FILE *out, const char *name)
|
||||
" -f, --grab show the menu before reading stdin. (wx)\n"
|
||||
" -n, --no-overlap adjust geometry to not overlap with panels. (w)\n"
|
||||
" -m, --monitor index of monitor where menu will appear. (x)\n"
|
||||
" -H, --line-height defines the height to make each menu line (0 = default height). (wx)\n"
|
||||
" --fn defines the font to be used ('name [size]'). (wx)\n"
|
||||
" --tb defines the title background color. (wx)\n"
|
||||
" --tf defines the title foreground color. (wx)\n"
|
||||
@ -125,6 +126,7 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
{ "grab", no_argument, 0, 'f' },
|
||||
{ "no-overlap", no_argument, 0, 'n' },
|
||||
{ "monitor", required_argument, 0, 'm' },
|
||||
{ "line-height", required_argument, 0, 'H' },
|
||||
{ "fn", required_argument, 0, 0x101 },
|
||||
{ "tb", required_argument, 0, 0x102 },
|
||||
{ "tf", required_argument, 0, 0x103 },
|
||||
@ -148,7 +150,7 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
* or parse them before running getopt.. */
|
||||
|
||||
for (;;) {
|
||||
int32_t opt = getopt_long(*argc, *argv, "hviwl:I:p:P:I:bfm:n", opts, NULL);
|
||||
int32_t opt = getopt_long(*argc, *argv, "hviwl:I:p:P:I:bfm:H:n", opts, NULL);
|
||||
if (opt < 0)
|
||||
break;
|
||||
|
||||
@ -198,6 +200,9 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
client->no_overlap = true;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
client->line_height = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 0x101:
|
||||
client->font = optarg;
|
||||
break;
|
||||
@ -262,6 +267,7 @@ menu_with_options(const struct client *client)
|
||||
return NULL;
|
||||
|
||||
bm_menu_set_font(menu, client->font);
|
||||
bm_menu_set_line_height(menu, client->line_height);
|
||||
bm_menu_set_title(menu, client->title);
|
||||
bm_menu_set_prefix(menu, client->prefix);
|
||||
bm_menu_set_filter_mode(menu, client->filter_mode);
|
||||
|
@ -10,6 +10,7 @@ struct client {
|
||||
const char *title;
|
||||
const char *prefix;
|
||||
const char *font;
|
||||
uint32_t line_height;
|
||||
uint32_t lines;
|
||||
uint32_t selected;
|
||||
uint32_t monitor;
|
||||
|
17
lib/bemenu.h
17
lib/bemenu.h
@ -385,6 +385,23 @@ bool bm_menu_set_font(struct bm_menu *menu, const char *font);
|
||||
*/
|
||||
const char* bm_menu_get_font(const struct bm_menu *menu);
|
||||
|
||||
/**
|
||||
* Set size of line in pixels.
|
||||
* Some renderers such as ncurses may ignore this when it does not make sense.
|
||||
*
|
||||
* @param menu bm_menu instance where to set line height.
|
||||
* @param line_height 0 for default line height, > 0 for that many pixels.
|
||||
*/
|
||||
void bm_menu_set_line_height(struct bm_menu *menu, uint32_t line_height);
|
||||
|
||||
/**
|
||||
* Get size of line in pixels.
|
||||
*
|
||||
* @param menu bm_menu instance where to get line height.
|
||||
* @return uint32_t for max amount of vertical lines to be shown.
|
||||
*/
|
||||
uint32_t bm_menu_get_line_height(struct bm_menu *menu);
|
||||
|
||||
/**
|
||||
* Set a hexadecimal color for element.
|
||||
*
|
||||
|
@ -224,6 +224,11 @@ struct bm_menu {
|
||||
*/
|
||||
struct bm_font font;
|
||||
|
||||
/**
|
||||
* Line height.
|
||||
*/
|
||||
uint32_t line_height;
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
14
lib/menu.c
14
lib/menu.c
@ -266,6 +266,20 @@ bm_menu_get_font(const struct bm_menu *menu)
|
||||
return menu->font.name;
|
||||
}
|
||||
|
||||
void
|
||||
bm_menu_set_line_height(struct bm_menu *menu, uint32_t line_height)
|
||||
{
|
||||
assert(menu);
|
||||
menu->line_height = line_height;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
bm_menu_get_line_height(struct bm_menu *menu)
|
||||
{
|
||||
assert(menu);
|
||||
return menu->line_height;
|
||||
}
|
||||
|
||||
bool
|
||||
bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *hex)
|
||||
{
|
||||
|
@ -166,10 +166,12 @@ bm_cairo_color_from_menu_color(const struct bm_menu *menu, enum bm_color color,
|
||||
}
|
||||
|
||||
__attribute__((unused)) static void
|
||||
bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *out_result)
|
||||
bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *out_result)
|
||||
{
|
||||
assert(cairo && menu && out_result);
|
||||
|
||||
uint32_t height = fmin(menu->line_height, max_height);
|
||||
|
||||
memset(out_result, 0, sizeof(struct cairo_paint_result));
|
||||
out_result->displayed = 1;
|
||||
|
||||
@ -189,21 +191,23 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma
|
||||
ascii_height = result.height;
|
||||
paint.baseline = result.baseline;
|
||||
|
||||
int32_t vpadding = height == 0 ? 2 : (height - ascii_height) / 2;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
uint32_t title_x = 0;
|
||||
if (menu->title) {
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_FG, &paint.fg);
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_BG, &paint.bg);
|
||||
paint.pos = (struct pos){ result.x_advance, 2 };
|
||||
paint.box = (struct box){ 4, 8, 2, 2, 0, ascii_height };
|
||||
paint.pos = (struct pos){ result.x_advance, vpadding };
|
||||
paint.box = (struct box){ 4, 8, vpadding, vpadding, 0, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", menu->title);
|
||||
title_x = result.x_advance;
|
||||
}
|
||||
|
||||
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);
|
||||
paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, 2 };
|
||||
paint.box = (struct box){ (menu->title ? 2 : 4), 0, 2, 2, width - paint.pos.x, ascii_height };
|
||||
paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, vpadding };
|
||||
paint.box = (struct box){ (menu->title ? 2 : 4), 0, vpadding, vpadding, width - paint.pos.x, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", (menu->filter ? menu->filter : ""));
|
||||
const uint32_t titleh = result.height;
|
||||
out_result->height = titleh;
|
||||
@ -247,12 +251,12 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma
|
||||
}
|
||||
|
||||
if (menu->prefix && highlighted) {
|
||||
paint.pos = (struct pos){ 0, 2 + posy };
|
||||
paint.box = (struct box){ 4 + spacing_x, 0, 2, 2, width - paint.pos.x, ascii_height };
|
||||
paint.pos = (struct pos){ 0, vpadding + posy };
|
||||
paint.box = (struct box){ 4 + spacing_x, 0, vpadding, vpadding, width - paint.pos.x, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : ""));
|
||||
} else {
|
||||
paint.pos = (struct pos){ 0, 2 + posy };
|
||||
paint.box = (struct box){ 4 + spacing_x + prefix_x, 0, 2, 2, width - paint.pos.x, ascii_height };
|
||||
paint.pos = (struct pos){ 0, vpadding + posy };
|
||||
paint.box = (struct box){ 4 + spacing_x + prefix_x, 0, vpadding, vpadding, width - paint.pos.x, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : ""));
|
||||
}
|
||||
|
||||
@ -283,8 +287,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma
|
||||
uint32_t cl = fmin(title_x + result.x_advance, width / 4);
|
||||
|
||||
if (menu->wrap || menu->index > 0) {
|
||||
paint.pos = (struct pos){ cl, 2 };
|
||||
paint.box = (struct box){ 1, 2, 2, 2, 0, ascii_height };
|
||||
paint.pos = (struct pos){ cl, vpadding };
|
||||
paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "<");
|
||||
cl += result.x_advance + 1;
|
||||
}
|
||||
@ -303,8 +307,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg);
|
||||
}
|
||||
|
||||
paint.pos = (struct pos){ cl, 2 };
|
||||
paint.box = (struct box){ 2, 4, 2, 2, 0, ascii_height };
|
||||
paint.pos = (struct pos){ cl, vpadding };
|
||||
paint.box = (struct box){ 2, 4, vpadding, vpadding, 0, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : ""));
|
||||
cl += result.x_advance + 2;
|
||||
out_result->displayed += (cl < width);
|
||||
@ -315,8 +319,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t ma
|
||||
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 - result.x_advance - 2, 2 };
|
||||
paint.box = (struct box){ 1, 2, 2, 2, 0, ascii_height };
|
||||
paint.pos = (struct pos){ width - result.x_advance - 2, vpadding };
|
||||
paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, ">");
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ struct window {
|
||||
bool render_pending;
|
||||
|
||||
struct {
|
||||
void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result);
|
||||
void (*render)(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result);
|
||||
} notify;
|
||||
};
|
||||
|
||||
|
@ -231,7 +231,7 @@ bm_wl_window_render(struct window *window, struct wl_display *display, const str
|
||||
break;
|
||||
|
||||
struct cairo_paint_result result;
|
||||
window->notify.render(&buffer->cairo, buffer->width, fmin(buffer->height, window->max_height), window->max_height, menu, &result);
|
||||
window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result);
|
||||
window->displayed = result.displayed;
|
||||
|
||||
if (window->height == result.height)
|
||||
|
@ -72,7 +72,7 @@ bm_x11_window_render(struct window *window, const struct bm_menu *menu)
|
||||
|
||||
cairo_push_group(buffer->cairo.cr);
|
||||
struct cairo_paint_result result;
|
||||
window->notify.render(&buffer->cairo, buffer->width, buffer->height, window->max_height, menu, &result);
|
||||
window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result);
|
||||
window->displayed = result.displayed;
|
||||
cairo_pop_group_to_source(buffer->cairo.cr);
|
||||
|
||||
|
@ -36,7 +36,7 @@ struct window {
|
||||
bool bottom;
|
||||
|
||||
struct {
|
||||
void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result);
|
||||
void (*render)(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result);
|
||||
} notify;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user