~leon_plickat/lavalauncher

c610e9c0d268bb193842b443cad18fe9b9eca213 — Leon Henrik Plickat a month ago 155fe80
Add rounded corners
M doc/lavalauncher.1.scd => doc/lavalauncher.1.scd +8 -0
@@ 161,6 161,14 @@ as follows.
	Position of the bar. Can be "top", "right", "bottom", "left". The bar
	will dock to that edge of the output(s). The default position is "bottom".

*radius*
	The radius of the corners. The Default is 5. Set to 0 to disable corner
	roundness.

*radius-{top-left, top-right, bottom-left, bottom-right}*
	The individual corner radia.


*size*
	Size of the bar. The default size is 80.


M src/bar/bar-pattern.c => src/bar/bar-pattern.c +47 -11
@@ 44,16 44,20 @@ static void sensible_defaults (struct Lava_bar_pattern *pattern)
	pattern->mode              = MODE_DEFAULT;
	pattern->layer             = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;

	pattern->size              = 80;
	pattern->icon_padding      = 2;
	pattern->border_top        = 2;
	pattern->border_right      = 2;
	pattern->border_bottom     = 2;
	pattern->border_left       = 2;
	pattern->margin_top        = 0;
	pattern->margin_right      = 0;
	pattern->margin_bottom     = 0;
	pattern->margin_left       = 0;
	pattern->size                = 80;
	pattern->icon_padding        = 2;
	pattern->border_top          = 2;
	pattern->border_right        = 2;
	pattern->border_bottom       = 2;
	pattern->border_left         = 2;
	pattern->radius_top_left     = 5;
	pattern->radius_top_right    = 5;
	pattern->radius_bottom_left  = 5;
	pattern->radius_bottom_right = 5;
	pattern->margin_top          = 0;
	pattern->margin_right        = 0;
	pattern->margin_bottom       = 0;
	pattern->margin_left         = 0;

	pattern->exclusive_zone    = 1;



@@ 501,6 505,33 @@ static bool bar_pattern_set_condition_transform (struct Lava_bar_pattern *patter
	return true;
}

static bool bar_pattern_set_radius (struct Lava_bar_pattern *pattern,
		const char *arg, const char direction)
{
	int32_t size = atoi(arg);
	if ( size < 0 )
	{
		log_message(NULL, 0, "ERROR: Radius must be equal to or greater than zero.\n");
		return false;
	}

	switch (direction)
	{
		case 'l': pattern->radius_top_left     = (uint32_t)size; break;
		case 'r': pattern->radius_top_right    = (uint32_t)size; break;
		case 'L': pattern->radius_bottom_left  = (uint32_t)size; break;
		case 'R': pattern->radius_bottom_right = (uint32_t)size; break;
		case 'a':
			pattern->radius_top_left     = (uint32_t)size;
			pattern->radius_top_right    = (uint32_t)size;
			pattern->radius_bottom_left  = (uint32_t)size;
			pattern->radius_bottom_right = (uint32_t)size;
			break;
	}
	return true;
}


struct
{
	const char *variable, direction;


@@ 531,7 562,12 @@ struct
	{ .variable = "cursor-name",          .set = bar_pattern_set_cursor_name,          .direction = '0'},
	{ .variable = "condition-scale",      .set = bar_pattern_set_condition_scale,      .direction = '0'},
	{ .variable = "condition-resolution", .set = bar_pattern_set_condition_resolution, .direction = '0'},
	{ .variable = "condition-transform",  .set = bar_pattern_set_condition_transform,  .direction = '0'}
	{ .variable = "condition-transform",  .set = bar_pattern_set_condition_transform,  .direction = '0'},
	{ .variable = "radius",               .set = bar_pattern_set_radius,               .direction = 'a'},
	{ .variable = "radius-top-left",      .set = bar_pattern_set_radius,               .direction = 'l'},
	{ .variable = "radius-top-right",     .set = bar_pattern_set_radius,               .direction = 'r'},
	{ .variable = "radius-bottom-left",   .set = bar_pattern_set_radius,               .direction = 'L'},
	{ .variable = "radius-bottom-right",  .set = bar_pattern_set_radius,               .direction = 'R'}
};

bool bar_pattern_set_variable (struct Lava_bar_pattern *pattern,

M src/bar/bar-pattern.h => src/bar/bar-pattern.h +1 -0
@@ 91,6 91,7 @@ struct Lava_bar_pattern

	uint32_t size, icon_padding;
	uint32_t border_top, border_right, border_bottom, border_left;
	uint32_t radius_top_left, radius_top_right, radius_bottom_left, radius_bottom_right;

	float bar_colour[4];
	float border_colour[4];

M src/bar/draw-generics.c => src/bar/draw-generics.c +89 -35
@@ 29,63 29,117 @@
#include"seat.h"
#include"draw-generics.h"

void lldg_circle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size)
void circle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size)
{
	cairo_arc(cairo, x + (size/2), y + (size/2), size / 2, 0, 2 * 3.1415927);
}

void lldg_rounded_square (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size)
void rounded_rectangle (cairo_t *cairo, uint32_t x, uint32_t y,
		uint32_t width, uint32_t height,
		double tl_r, double tr_r, double bl_r, double br_r)
{
	double radius = size / 10.0, degrees = 3.1415927 / 180.0;
	double degrees = 3.1415927 / 180.0;

	cairo_new_sub_path(cairo);
	cairo_arc(cairo, x + size - radius, y + radius, radius,
			-90 * degrees, 0 * degrees);
	cairo_arc(cairo, x + size - radius, y + size - radius,
			radius, 0 * degrees, 90 * degrees);
	cairo_arc(cairo, x + radius, y + size - radius, radius,
			90 * degrees, 180 * degrees);
	cairo_arc(cairo, x + radius, y + radius, radius,
			180 * degrees, 270 * degrees);
	cairo_arc(cairo, x + width - tr_r,          y + tr_r, tr_r, -90 * degrees,   0 * degrees);
	cairo_arc(cairo, x + width - br_r, y + height - br_r, br_r,   0 * degrees,  90 * degrees);
	cairo_arc(cairo, x +         bl_r, y + height - bl_r, bl_r,  90 * degrees, 180 * degrees);
	cairo_arc(cairo, x +         tl_r, y          + tl_r, tl_r, 180 * degrees, 270 * degrees);
	cairo_close_path(cairo);
}

/* Draw a rectangle with borders. */
void lldg_draw_bordered_rectangle (cairo_t *cairo, uint32_t x, uint32_t y,
		uint32_t w, uint32_t h, uint32_t border_top, uint32_t border_right,
/* Draw a rectangle with configurable borders and corners. */
void draw_bar_background (cairo_t *cairo,
		uint32_t x, uint32_t y, uint32_t w, uint32_t h,
		uint32_t border_top, uint32_t border_right,
		uint32_t border_bottom, uint32_t border_left,
		uint32_t top_left_radius, uint32_t top_right_radius,
		uint32_t bottom_left_radius, uint32_t bottom_right_radius,
		uint32_t scale, float center_colour[4], float border_colour[4])
{
	/* Scale. */
	x *= scale, y *= scale, w *= scale, h *= scale;
	border_top *= scale, border_bottom *= scale;
	border_left *= scale, border_right *= scale;
	top_left_radius *= scale, top_right_radius *= scale;
	bottom_left_radius *= scale, bottom_right_radius *= scale;

	/* Calculate dimensions of center. */
	uint32_t cx = x + border_left,
		cy = y + border_top,
		cw = w - border_left - border_right,
		ch = h - border_top  - border_bottom;
	cairo_save(cairo);
	cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);

	if ( top_left_radius == 0 && top_right_radius == 0
			&& bottom_left_radius == 0 && bottom_right_radius == 0 )
	{
		if ( border_top == 0 && border_bottom == 0
				&& border_left == 0 && border_right == 0 )
		{
			cairo_rectangle(cairo, x, y, w, h);
			cairo_set_source_rgba(cairo, center_colour[0], center_colour[1],
					center_colour[2], center_colour[3]);
			cairo_fill(cairo);
		}
		else
		{
			fputs("here\n", stderr);
			/* Calculate dimensions of center. */
			uint32_t cx = x + border_left,
				cy = y + border_top,
				cw = w - (border_left + border_right),
				ch = h - (border_top + border_bottom);

	/* Draw center. */
	cairo_rectangle(cairo, cx, cy, cw, ch);
	cairo_set_source_rgba(cairo, center_colour[0], center_colour[1],
			center_colour[2], center_colour[3]);
	cairo_fill(cairo);
			/* Borders. */
			cairo_rectangle(cairo, x, y, w, border_top);
			cairo_rectangle(cairo, x + w - border_right, y + border_top,
					border_right, h - border_top - border_bottom);
			cairo_rectangle(cairo, x, y + h - border_bottom, w, border_bottom);
			cairo_rectangle(cairo, x, y + border_top, border_left,
					h - border_top - border_bottom);
			cairo_set_source_rgba(cairo, border_colour[0], border_colour[1],
					border_colour[2], border_colour[3]);
			cairo_fill(cairo);

	/* Draw borders. Top - Right - Bottom - Left */
	cairo_rectangle(cairo, x, y, w, border_top);
	cairo_rectangle(cairo, x + w - border_right, y + border_top,
			border_right, h - border_top - border_bottom);
	cairo_rectangle(cairo, x, y + h - border_bottom, w, border_bottom);
	cairo_rectangle(cairo, x, y + border_top, border_left,
			h - border_top - border_bottom);
	cairo_set_source_rgba(cairo, border_colour[0], border_colour[1],
			border_colour[2], border_colour[3]);
	cairo_fill(cairo);
			/* Center. */
			cairo_rectangle(cairo, cx, cy, cw, ch);
			cairo_set_source_rgba(cairo, center_colour[0], center_colour[1],
					center_colour[2], center_colour[3]);
			cairo_fill(cairo);
		}
	}
	else
	{
		if ( border_top == 0 && border_bottom == 0
				&& border_left == 0 && border_right == 0 )
		{
			rounded_rectangle(cairo, x, y, w, h,
					top_left_radius, top_right_radius,
					bottom_left_radius, bottom_right_radius);
			cairo_set_source_rgba(cairo, center_colour[0], center_colour[1],
					center_colour[2], center_colour[3]);
			cairo_fill(cairo);
		}
		else
		{
			rounded_rectangle(cairo, x, y, w, h,
					top_left_radius, top_right_radius,
					bottom_left_radius, bottom_right_radius);
			cairo_set_source_rgba(cairo, border_colour[0], border_colour[1],
					border_colour[2], border_colour[3]);
			cairo_fill(cairo);

			rounded_rectangle(cairo, x + border_left, y + border_top,
					w - (border_left + border_right),
					h - (border_bottom + border_top),
					top_left_radius, top_right_radius,
					bottom_left_radius, bottom_right_radius);
			cairo_set_source_rgba(cairo, center_colour[0], center_colour[1],
					center_colour[2], center_colour[3]);
			cairo_fill(cairo);
		}
	}
	cairo_restore(cairo);
}

void lldg_clear_buffer (cairo_t *cairo)
void clear_buffer (cairo_t *cairo)
{
	cairo_save(cairo);
	cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);

M src/bar/draw-generics.h => src/bar/draw-generics.h +10 -5
@@ 26,12 26,17 @@
struct Lava_data;
struct Lava_bar;

void lldg_circle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size);
void lldg_rounded_square (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size);
void lldg_draw_bordered_rectangle (cairo_t *cairo, uint32_t x, uint32_t y,
		uint32_t w, uint32_t h, uint32_t border_top, uint32_t border_right,
void circle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size);
void rounded_rectangle (cairo_t *cairo, uint32_t x, uint32_t y,
		uint32_t width, uint32_t height,
		double tl_r, double tr_r, double bl_r, double br_r);
void draw_bar_background (cairo_t *cairo,
		uint32_t x, uint32_t y, uint32_t w, uint32_t h,
		uint32_t border_top, uint32_t border_right,
		uint32_t border_bottom, uint32_t border_left,
		uint32_t top_left_radius, uint32_t top_right_radius,
		uint32_t bottom_left_radius, uint32_t bottom_right_radius,
		uint32_t scale, float center_colour[4], float border_colour[4]);
void lldg_clear_buffer (cairo_t *cairo);
void clear_buffer (cairo_t *cairo);

#endif

M src/bar/render.c => src/bar/render.c +8 -4
@@ 67,11 67,13 @@ static void draw_effect (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t size,
			break;

		case EFFECT_PHONE:
			lldg_rounded_square(cairo, x, y, size);
			rounded_rectangle(cairo, x, y, size, size,
					size / 10.0, size / 10.0,
					size / 10.0, size / 10.0);
			break;

		case EFFECT_CIRCLE:
			lldg_circle(cairo, x, y, size);
			circle(cairo, x, y, size);
			break;

		default:


@@ 133,14 135,16 @@ void render_bar_frame (struct Lava_bar *bar)
		return;

	cairo_t *cairo = bar->current_buffer->cairo;
	lldg_clear_buffer(cairo);
	clear_buffer(cairo);

	/* Draw bar. */
	log_message(data, 2, "[render] Drawing bar.\n");
	lldg_draw_bordered_rectangle(cairo,
	draw_bar_background(cairo,
			bar->bar_x, bar->bar_y, bar->bar_width, bar->bar_height,
			pattern->border_top, pattern->border_right,
			pattern->border_bottom, pattern->border_left,
			pattern->radius_top_left, pattern->radius_top_right,
			pattern->radius_bottom_left, pattern->radius_bottom_right,
			scale, pattern->bar_colour, pattern->border_colour);

	/* Draw icons. */