From 6dd4c979c40804756ef4d3ca5ac34671c3bcc7e2 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sun, 19 Nov 2023 00:00:44 +0100 Subject: Compute the layout for the buttons --- src/draw.c | 105 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 35 deletions(-) (limited to 'src/draw.c') diff --git a/src/draw.c b/src/draw.c index 0122ab4..8a2a6bd 100644 --- a/src/draw.c +++ b/src/draw.c @@ -12,6 +12,20 @@ // (this will also work for animations in the future) // or use some flags to trigger drawing +typedef struct { + Button *btn; + int x, y; + int width, height; + int text_w, text_h; + PangoLayout *pl; +} Layout; + +static void layout_destroy(Layout *layout) +{ + g_object_unref(layout->pl); + g_free(layout); +} + Drawable *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad, double alpha) { Drawable *draw = g_malloc(sizeof(Drawable)); @@ -28,6 +42,8 @@ Drawable *draw_create(const char *font, int height, int left_pad, int right_pad, draw->alpha = alpha; g_assert(alpha >= 0 && alpha <= 1); + draw->layouts = NULL; + log_debug("Draw context created [height=%d, left_pad=%d, right_pad=%d, top_pad=%d, alpha=%.2lf]", height, left_pad, right_pad, top_pad, alpha); return draw; @@ -72,56 +88,33 @@ void draw_paint(Drawable *draw, Window *win) int line_w = 1 * scale; cairo_set_line_width(cr, line_w); - int bx = 0; - - for (GList *it = draw->btns; it; it = it->next) { - Button *btn = it->data; - - PangoLayout *layout = pango_cairo_create_layout(cr); - pango_layout_set_font_description(layout, draw->desc); - - int bwidth = height, bheight = height; - - pango_layout_set_text(layout, btn->text, -1); - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + for (GList *it = draw->layouts; it; it = it->next) { + Layout *layout = it->data; - int text_w, text_h; - pango_layout_get_pixel_size(layout, &text_w, &text_h); - text_w = ceil(text_w / scale); - text_h = ceil(text_h / scale); - - if (!btn->fixed_size) { - bwidth = text_w + 2 * radius; - } - - int text_x = bx + (bwidth / 2) - (text_w / 2); - int text_y = (bheight / 2) - (text_h / 2); + int text_x = layout->x + (layout->width / 2) - (layout->text_w / 2); + int text_y = layout->y + (layout->height / 2) - (layout->text_h / 2); // purple cairo_set_source_rgba(cr, 0.502, 0.168, 0.886, 1); cairo_new_sub_path(cr); - cairo_arc(cr, bx + radius, radius, radius, 90 * degree, 270 * degree); - cairo_arc(cr, bx + bwidth - radius, radius, radius, 270 * degree, 450 * degree); + cairo_arc(cr, layout->x + radius, layout->y + radius, radius, 90 * degree, 270 * degree); + cairo_arc(cr, layout->x + layout->width - radius, layout->y + radius, radius, 270 * degree, 450 * degree); cairo_close_path(cr); cairo_fill(cr); cairo_set_source_rgba(cr, 0.8, 0.8, 0.8, 1); cairo_new_sub_path(cr); - cairo_arc(cr, bx + radius, radius, radius - line_w , 90 * degree, 270 * degree); - cairo_arc(cr, bx + bwidth - radius, radius, radius - line_w, 270 * degree, 450 * degree); + cairo_arc(cr, layout->x + radius, layout->y + radius, radius - line_w , 90 * degree, 270 * degree); + cairo_arc(cr, layout->x + layout->width - radius, layout->y + radius, radius - line_w, 270 * degree, 450 * degree); cairo_close_path(cr); cairo_stroke(cr); cairo_set_source_rgb(cr, 0.8, 0.8, 0.8); cairo_move_to(cr, text_x, text_y); - pango_cairo_update_layout(cr, layout); - pango_cairo_show_layout(cr, layout); + pango_cairo_update_layout(cr, layout->pl); + pango_cairo_show_layout(cr, layout->pl); - g_object_unref(layout); - - int sep = 10 * scale; - bx += height + line_w * 2 + sep; } cairo_destroy(cr); @@ -134,13 +127,55 @@ void draw_paint(Drawable *draw, Window *win) cairo_surface_destroy(surface); } -void draw_set_buttons(Drawable *draw, GList *btns) +void draw_compute_layout(Drawable *draw, GList *btns, cairo_t *cr) { - draw->btns = btns; + g_list_free_full(draw->layouts, (GDestroyNotify)layout_destroy); + draw->layouts = NULL; + + // FIXME: Does not work for scale != 1 + //double scale = window_get_scale(win); + double scale = 1; + + int x = 0; + int height = round(draw->height * scale); + int radius = height / 2; + + for (GList *it = btns; it; it = it->next) { + Button *btn = it->data; + + Layout *layout = g_malloc(sizeof(Layout)); + layout->btn = btn; + + layout->x = x; + layout->y = 0; + + layout->pl = pango_cairo_create_layout(cr); + pango_layout_set_font_description(layout->pl, draw->desc); + pango_layout_set_text(layout->pl, btn->text, -1); + pango_layout_set_alignment(layout->pl, PANGO_ALIGN_CENTER); + + int text_w, text_h; + pango_layout_get_pixel_size(layout->pl, &text_w, &text_h); + + layout->text_w = ceil(text_w / scale); + layout->text_h = ceil(text_h / scale); + + layout->width = btn->fixed_size ? height : layout->text_w + 2 * radius; + layout->height = height; + + draw->layouts = g_list_append(draw->layouts, layout); + + int sep = 10 * scale; + int line_w = 1 * scale; + x += height + line_w * 2 + sep; + } + + log_debug("Updated layouts"); } void draw_destroy(Drawable *draw) { + g_list_free_full(draw->layouts, (GDestroyNotify)layout_destroy); pango_font_description_free(draw->desc); g_free(draw); } -- cgit v1.2.3