diff options
| author | Federico Angelilli <code@fedang.net> | 2023-11-19 00:00:44 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2023-11-19 00:00:44 +0100 |
| commit | 6dd4c979c40804756ef4d3ca5ac34671c3bcc7e2 (patch) | |
| tree | df72dcbcb435f618c109928e88fc36d887e5f220 /src | |
| parent | bab8d5a6c2c6d56a97802bd23b2f5e03f0bec417 (diff) | |
Compute the layout for the buttons
Diffstat (limited to 'src')
| -rw-r--r-- | src/comet.c | 2 | ||||
| -rw-r--r-- | src/draw.c | 105 | ||||
| -rw-r--r-- | src/draw.h | 7 |
3 files changed, 74 insertions, 40 deletions
diff --git a/src/comet.c b/src/comet.c index df5ffe4..21bad7a 100644 --- a/src/comet.c +++ b/src/comet.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) Button *btn = button_create("long button", false); state_add_button(state, btn); - draw_set_buttons(draw, state->btns); + draw_compute_layout(draw, state->btns, window_get_context(win)); connect_attach_state(con, state); connect_attach_source(con); @@ -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); } @@ -3,25 +3,24 @@ #include <glib.h> #include <pango/pango-font.h> -#include <pango/pango-types.h> #include "window.h" typedef struct Drawable Drawable; struct Drawable { - PangoFontDescription *desc; int height; int left_pad; int right_pad; int top_pad; double alpha; - GList *btns; + GList *layouts; + PangoFontDescription *desc; }; Drawable *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad, double alpha); -void draw_set_buttons(Drawable *draw, GList *btns); +void draw_compute_layout(Drawable *draw, GList *btns, cairo_t *cr); void draw_paint(Drawable *draw, Window *win); |
