1
0
mirror of https://github.com/Cloudef/bemenu synced 2024-11-23 09:21:59 +01:00

Add option to define a border and border color

This commit is contained in:
Barbaross 2022-05-31 18:45:20 -04:00 committed by Jari Vetoniemi
parent 84bccc02a0
commit 8c1c29c0b9
6 changed files with 80 additions and 16 deletions

@ -202,6 +202,7 @@ usage(FILE *out, const char *name)
" -H, --line-height defines the height to make each menu line (0 = default height). (wx)\n"
" -M, --margin defines the empty space on either side of the menu. (wx)\n"
" -W, --width-factor defines the relative width factor of the menu (from 0 to 1). (wx)\n"
" -B, --border defines the width of the border in pixels around the menu. (wx)\n"
" --ch defines the height of the cursor (0 = scales with line height). (wx)\n"
" --cw defines the width of the cursor. (wx)\n"
" --hp defines the horizontal padding for the entries in single line mode. (wx)\n"
@ -221,7 +222,8 @@ usage(FILE *out, const char *name)
" --ab defines the alternating background color. (wx)\n"
" --af defines the alternating foreground color. (wx)\n"
" --scb defines the scrollbar background color. (wx)\n"
" --scf defines the scrollbar foreground color. (wx)\n", out);
" --scf defines the scrollbar foreground color. (wx)\n"
" --bdr defines the border color. (wx)\n", out);
exit((out == stderr ? EXIT_FAILURE : EXIT_SUCCESS));
}
@ -274,6 +276,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
{ "line-height", required_argument, 0, 'H' },
{ "margin", required_argument, 0, 'M' },
{ "width-factor", required_argument, 0, 'W' },
{ "border", required_argument, 0, 'B' },
{ "ch", required_argument, 0, 0x120 },
{ "cw", required_argument, 0, 0x125 },
{ "hp", required_argument, 0, 0x122 },
@ -294,6 +297,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
{ "af", required_argument, 0, 0x124 },
{ "scb", required_argument, 0, 0x114 },
{ "scf", required_argument, 0, 0x115 },
{ "bdr", required_argument, 0, 0x121 },
{ "disco", no_argument, 0, 0x116 },
{ 0, 0, 0, 0 }
@ -309,7 +313,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
for (optind = 0;;) {
int32_t opt;
if ((opt = getopt_long(*argc, *argv, "hviwxcl:I:p:P:I:bfm:H:M:W:ns", opts, NULL)) < 0)
if ((opt = getopt_long(*argc, *argv, "hviwxcl:I:p:P:I:bfm:H:M:W:B:ns", opts, NULL)) < 0)
break;
switch (opt) {
@ -385,6 +389,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
case 'W':
client->width_factor = strtof(optarg, NULL);
break;
case 'B':
client->border_size = strtol(optarg, NULL, 10);
break;
case 0x120:
client->cursor_height = strtol(optarg, NULL, 10);
break;
@ -445,6 +452,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
case 0x115:
client->colors[BM_COLOR_SCROLLBAR_FG] = optarg;
break;
case 0x121:
client->colors[BM_COLOR_BORDER] = optarg;
break;
case 0x116:
disco();
@ -499,6 +509,7 @@ menu_with_options(struct client *client)
bm_menu_set_spacing(menu, !client->no_spacing);
bm_menu_set_password(menu, client->password);
bm_menu_set_width(menu, client->hmargin_size, client->width_factor);
bm_menu_set_border_size(menu, client->border_size);
if (client->center) {
bm_menu_set_align(menu, BM_ALIGN_CENTER);

@ -20,6 +20,7 @@ struct client {
uint32_t selected;
uint32_t monitor;
uint32_t hmargin_size;
uint32_t border_size;
float width_factor;
bool bottom;
bool center;

@ -347,6 +347,7 @@ enum bm_color {
BM_COLOR_ALTERNATE_FG,
BM_COLOR_SCROLLBAR_BG,
BM_COLOR_SCROLLBAR_FG,
BM_COLOR_BORDER,
BM_COLOR_LAST
};
@ -613,6 +614,24 @@ BM_PUBLIC uint32_t bm_menu_get_height(struct bm_menu *menu);
*/
BM_PUBLIC uint32_t bm_menu_get_width(struct bm_menu *menu);
/**
* Set the size of the border for the bar
*
* @param menu bm_menu to get border size from.
* @return border size of the menu.
*/
BM_PUBLIC void bm_menu_set_border_size(struct bm_menu* menu, uint32_t border_size);
/**
* Get the size of the border for the bar
*
* @param menu bm_menu to get border size from.
* @return border size of the menu.
*/
BM_PUBLIC uint32_t bm_menu_get_border_size(struct bm_menu* menu);
/**
* Set a hexadecimal color for element.
*

@ -377,6 +377,11 @@ struct bm_menu {
*/
float width_factor;
/**
* Border size
*/
uint32_t border_size;
/**
* Is menu grabbed?
*/

@ -31,6 +31,7 @@ static const char *default_colors[BM_COLOR_LAST] = {
"#121212FF", // BM_COLOR_ALTERNATE_FG
"#121212FF", // BM_COLOR_SCROLLBAR_BG
"#D81860FF", // BM_COLOR_SCROLLBAR_FG
"#D81860FF", // BM_COLOR_BORDER
};
/**
@ -333,6 +334,20 @@ bm_menu_get_hpadding(struct bm_menu *menu)
return menu->hpadding;
}
void
bm_menu_set_border_size(struct bm_menu* menu, uint32_t border_size)
{
assert(menu);
menu->border_size = border_size;
}
uint32_t
bm_menu_get_border_size(struct bm_menu* menu)
{
assert(menu);
return menu->border_size;
}
uint32_t
bm_menu_get_height(struct bm_menu *menu)
{

@ -275,6 +275,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
ascii_height = result.height;
paint.baseline = result.baseline;
uint32_t border_size = menu->border_size;
width -= border_size;
uint32_t height = fmin(fmax(menu->line_height, ascii_height), max_height);
uint32_t vpadding = (height - ascii_height)/2;
@ -291,8 +293,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
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, vpadding };
paint.box = (struct box){ 4, 8, vpadding, -vpadding, 0, height };
paint.pos = (struct pos){ result.x_advance + border_size + 4, vpadding + border_size };
paint.box = (struct box){ 4, 16, vpadding, -vpadding, 0, height };
bm_cairo_draw_line(cairo, &paint, &result, "%s", menu->title);
title_x = result.x_advance;
}
@ -303,7 +305,7 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
paint.cursor = menu->cursor;
paint.cursor_height = menu->cursor_height;
paint.cursor_width = menu->cursor_width;
paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, vpadding };
paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance + border_size, vpadding + border_size };
paint.box = (struct box){ (menu->title ? 2 : 4), 0, vpadding, -vpadding, width - paint.pos.x, height };
const char *filter_text = (menu->filter ? menu->filter : "");
@ -320,7 +322,8 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
uint32_t count;
struct bm_item **items = bm_menu_get_filtered_items(menu, &count);
uint32_t lines = (menu->lines > 0 ? menu->lines : 1);
uint32_t page_length = 0;
if (menu->lines > 0) {
/* vertical mode */
@ -371,11 +374,11 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
char *line_str = bm_cairo_entry_message(items[i]->text, highlighted, menu->event_feedback, i, count);
if (menu->prefix && highlighted) {
paint.pos = (struct pos){ spacing_x, posy+vpadding };
paint.pos = (struct pos){ spacing_x + border_size, posy+vpadding + border_size };
paint.box = (struct box){ 4, 0, vpadding, -vpadding, width - paint.pos.x, height };
bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, line_str);
} else {
paint.pos = (struct pos){ spacing_x, posy+vpadding };
paint.pos = (struct pos){ spacing_x + border_size, posy+vpadding + border_size };
paint.box = (struct box){ 4 + prefix_x, 0, vpadding, -vpadding, width - paint.pos.x, height };
bm_cairo_draw_line(cairo, &paint, &result, "%s", line_str);
}
@ -383,13 +386,14 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
posy += (spacing_y ? spacing_y : result.height);
out_result->height = posy;
out_result->displayed++;
page_length += 1;
}
if (spacing_x) {
bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg);
const uint32_t sheight = out_result->height - titleh;
cairo_set_source_rgba(cairo->cr, paint.bg.r, paint.bg.b, paint.bg.g, paint.bg.a);
cairo_rectangle(cairo->cr, scrollbar_w, titleh, spacing_x - scrollbar_w, sheight);
cairo_rectangle(cairo->cr, scrollbar_w + border_size, titleh + border_size, spacing_x - scrollbar_w, sheight);
cairo_fill(cairo->cr);
}
@ -399,14 +403,15 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
const uint32_t sheight = out_result->height - titleh;
cairo_set_source_rgba(cairo->cr, paint.bg.r, paint.bg.b, paint.bg.g, paint.bg.a);
cairo_rectangle(cairo->cr, 0, titleh, scrollbar_w, sheight);
cairo_rectangle(cairo->cr, border_size, titleh + border_size, scrollbar_w, sheight);
cairo_fill(cairo->cr);
const float percent = fmin(((float)page / (count - lines)), 1.0f);
const uint32_t size = fmax(sheight * ((float)lines / count), 2.0f);
const float fraction = fmin((float)lines / count, 1.0f);
const uint32_t size = fmax(sheight * fraction, 2.0f);
const uint32_t posy = percent * (sheight - size);
cairo_set_source_rgba(cairo->cr, paint.fg.r, paint.fg.b, paint.fg.g, paint.fg.a);
cairo_rectangle(cairo->cr, 0, titleh + posy, scrollbar_w, size);
cairo_rectangle(cairo->cr, border_size, titleh + posy + border_size, scrollbar_w, size);
cairo_fill(cairo->cr);
}
} else {
@ -415,13 +420,13 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
uint32_t cl = fmin(title_x + result.x_advance, width / 4);
if (count > 0) {
paint.pos = (struct pos){ cl, vpadding };
paint.pos = (struct pos){ cl, vpadding + border_size };
paint.box = (struct box){ 1, 2, vpadding, -vpadding, 0, height };
bm_cairo_draw_line(cairo, &paint, &result, (count > 0 && (menu->wrap || menu->index > 0) ? "<" : " "));
cl += result.x_advance + 1;
}
for (uint32_t i = menu->index; i < count && cl < (width/cairo->scale); ++i) {
for (uint32_t i = menu->index; i < count && cl < (width/cairo->scale); ++i) {
bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu));
if (highlighted) {
@ -439,7 +444,7 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
}
uint32_t hpadding = (menu->hpadding == 0 ? 2 : menu->hpadding);
paint.pos = (struct pos){ cl + (hpadding/2), vpadding };
paint.pos = (struct pos){ cl + (hpadding/2), vpadding + border_size };
paint.box = (struct box){ hpadding/2, 1.5 * hpadding, vpadding, -vpadding, 0, height };
bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : ""));
cl += result.x_advance + (0.5 * hpadding);
@ -451,12 +456,20 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
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 };
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, ">");
}
}
// Draw borders
bm_cairo_color_from_menu_color(menu, BM_COLOR_BORDER, &paint.fg);
cairo_set_source_rgba(cairo->cr, paint.fg.r, paint.fg.b, paint.fg.g, paint.fg.a);
cairo_rectangle(cairo->cr, 0, 0, width + border_size, (height * (page_length + 1)) + (2 * border_size));
cairo_set_line_width(cairo->cr, 2 * menu->border_size);
cairo_stroke(cairo->cr);
out_result->height += 2 * border_size;
out_result->height *= cairo->scale;
}