diff --git a/CHANGELOG.md b/CHANGELOG.md index 84f80e3..d102c7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Added * ramp: can now have custom min and max values (https://codeberg.org/dnkl/yambar/issues/103). +* border: new decoration. ### Changed diff --git a/decorations/border.c b/decorations/border.c new file mode 100644 index 0000000..ac50c33 --- /dev/null +++ b/decorations/border.c @@ -0,0 +1,93 @@ +#include + +#include "../config.h" +#include "../config-verify.h" +#include "../decoration.h" +#include "../plugin.h" + +#define LOG_MODULE "border" +#define LOG_ENABLE_DBG 0 +#include "../log.h" + +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) + +struct private { + pixman_color_t color; + int size; +}; + +static void +destroy(struct deco *deco) +{ + struct private *d = deco->private; + free(d); + free(deco); +} + +static void +expose(const struct deco *deco, pixman_image_t *pix, int x, int y, int width, int height) +{ + const struct private *d = deco->private; + pixman_image_fill_rectangles( + PIXMAN_OP_OVER, pix, &d->color, 4, + (pixman_rectangle16_t []){ + /* Top */ + {x, y, width, min(d->size, height)}, + + /* Bottom */ + {x, max(y + height - d->size, y), width, min(d->size, height)}, + + /* Left */ + {x, y, min(d->size, width), height}, + + /* Right */ + {max(x + width - d->size, x), y, min(d->size, width), height}, + }); +} + +static struct deco * +border_new(pixman_color_t color, int size) +{ + struct private *priv = calloc(1, sizeof(*priv)); + priv->color = color; + priv->size = size; + + struct deco *deco = calloc(1, sizeof(*deco)); + deco->private = priv; + deco->expose = &expose; + deco->destroy = &destroy; + + return deco; +} + +static struct deco * +from_conf(const struct yml_node *node) +{ + const struct yml_node *color = yml_get_value(node, "color"); + const struct yml_node *size = yml_get_value(node, "size"); + return border_new( + conf_to_color(color), + size != NULL ? yml_value_as_int(size) : 1); +} + +static bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static const struct attr_info attrs[] = { + {"color", true, &conf_verify_color}, + {"size", false, &conf_verify_int}, + DECORATION_COMMON_ATTRS, + }; + + return conf_verify_dict(chain, node, attrs); +} + +const struct deco_iface deco_border_iface = { + .verify_conf = &verify_conf, + .from_conf = &from_conf, +}; + +#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES) +extern const struct deco_iface iface __attribute__((weak, alias("deco_border_iface"))); +#endif diff --git a/decorations/meson.build b/decorations/meson.build index 708267e..e8b289c 100644 --- a/decorations/meson.build +++ b/decorations/meson.build @@ -1,7 +1,7 @@ deco_sdk = declare_dependency(dependencies: [pixman, tllist, fcft]) decorations = [] -foreach deco : ['background', 'stack', 'underline'] +foreach deco : ['background', 'border', 'stack', 'underline'] if plugs_as_libs shared_module('@0@'.format(deco), '@0@.c'.format(deco), dependencies: deco_sdk, diff --git a/doc/yambar-decorations.5.scd b/doc/yambar-decorations.5.scd index 48dcc87..8c972f2 100644 --- a/doc/yambar-decorations.5.scd +++ b/doc/yambar-decorations.5.scd @@ -70,6 +70,39 @@ content: color: ff0000ff ``` + +# BORDER + +This decoration renders a border of configurable size (i.e border +width) around the particle. + +## CONFIGURATION + +[[ *Name* +:[ *Type* +:[ *Req* +:[ *Description* +| color +: color +: yes +: The color of the line. See *yambar*(5) for format. +| size +: int +: no +: Border width, in pixels. Defaults to 1px. + +## EXAMPLES + +``` +content: + string: + deco: + border: + size: 2 + color: ff0000ff +``` + + # STACK This particles combines multiple decorations. diff --git a/plugin.c b/plugin.c index 00b0061..5f31b2e 100644 --- a/plugin.c +++ b/plugin.c @@ -58,6 +58,7 @@ EXTERN_PARTICLE(ramp); EXTERN_PARTICLE(string); EXTERN_DECORATION(background); +EXTERN_DECORATION(border); EXTERN_DECORATION(stack); EXTERN_DECORATION(underline); @@ -144,6 +145,7 @@ init(void) REGISTER_CORE_PARTICLE(string, string); REGISTER_CORE_DECORATION(background, background); + REGISTER_CORE_DECORATION(border, border); REGISTER_CORE_DECORATION(stack, stack); REGISTER_CORE_DECORATION(underline, underline);