aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2023-11-26 21:26:03 +0100
committerFederico Angelilli <code@fedang.net>2023-11-26 21:26:03 +0100
commit238bedb3f4d3a356a6cd11cd8b4c5a2725de2cf8 (patch)
treed5b74c202aa364ccdd4d7e3d3423bbcf00420330 /src
parentf1fe3ce9e29a1dcb4000bedce6eb9bdeebd08f59 (diff)
Implement button groups
Diffstat (limited to 'src')
-rw-r--r--src/comet.c15
-rw-r--r--src/draw.c93
2 files changed, 79 insertions, 29 deletions
diff --git a/src/comet.c b/src/comet.c
index 8fd5095..07fb8cf 100644
--- a/src/comet.c
+++ b/src/comet.c
@@ -307,6 +307,21 @@ int main(int argc, char **argv)
button_simple_set_action(q_btn, quit_action, mainloop);
state_add_button(state, q_btn);
+ // Test button group
+ Button *child1 = button_simple_create(PANGO_ALIGN_CENTER, color, line_color);
+ button_simple_set_text(child1, "C1", text_color);
+ button_simple_set_action(child1, show_action, &date_ctx);
+
+ Button *child2 = button_simple_create(PANGO_ALIGN_CENTER, color, line_color);
+ button_simple_set_text(child2, "C2", text_color);
+ button_simple_set_action(child2, show_action, &date_ctx);
+
+ Color orange = { 1, 0.647, 0, 1 };
+ Button *group = button_group_create(PANGO_ALIGN_LEFT, orange, line_color);
+ button_group_append(group, child1);
+ button_group_append(group, child2);
+ state_add_button(state, group);
+
connect_attach_state(con, state);
connect_attach_source(con);
diff --git a/src/draw.c b/src/draw.c
index 8bf190f..5aa4837 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -10,7 +10,7 @@
static void layout_destroy(Layout *layout)
{
- g_object_unref(layout->pl);
+ if (layout->pl != NULL) g_object_unref(layout->pl);
g_free(layout);
}
@@ -87,9 +87,6 @@ void draw_paint(Drawable *draw, Window *win)
for (GList *it = draw->layouts; it; it = it->next) {
Layout *layout = it->data;
- int text_x = layout->x + (layout->width / 2) - (layout->text_w / 2);
- int text_y = layout->y + (layout->height / 2) - (layout->text_h / 2);
-
Color color = layout->btn->color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_new_sub_path(cr);
@@ -107,7 +104,10 @@ void draw_paint(Drawable *draw, Window *win)
cairo_stroke(cr);
if (layout->btn->simple) {
- color = ((ButtonSimple *)layout->btn)->text_color;
+ int text_x = layout->x + (layout->width / 2) - (layout->text_w / 2);
+ int text_y = layout->y + (layout->height / 2) - (layout->text_h / 2);
+
+ color = CAST(layout->btn, ButtonSimple)->text_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_move_to(cr, text_x, text_y);
@@ -136,6 +136,28 @@ static gint align_compare(gconstpointer a, gconstpointer b)
return 0;
}
+// Works only for simple buttons
+static void layout_text(Layout *layout, PangoFontDescription *desc, double scale, int height, int radius)
+{
+ const char *text = CAST(layout->btn, ButtonSimple)->text;
+
+ pango_layout_set_font_description(layout->pl, desc);
+ pango_layout_set_text(layout->pl, 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);
+
+ // If there is only one glyph the button should be round
+ size_t text_l = g_utf8_strlen(text, -1);
+
+ layout->width = text_l == 1 ? height : layout->text_w + 2 * radius;
+ layout->height = height;
+}
+
void draw_compute_layout(Drawable *draw, Window *win, GList *btns)
{
g_list_free_full(draw->layouts, (GDestroyNotify)layout_destroy);
@@ -168,43 +190,56 @@ void draw_compute_layout(Drawable *draw, Window *win, GList *btns)
Layout *layout = g_malloc(sizeof(Layout));
layout->btn = btn;
+ if (prev != NULL && prev->align == btn->align) x += sep;
+
layout->x = x;
layout->y = 0;
- //FIXME
- const char *text = btn->simple ? ((ButtonSimple *)btn)->text : "x";
+ draw->layouts = g_list_prepend(draw->layouts, layout);
- layout->pl = pango_cairo_create_layout(window_get_context(win));
- pango_layout_set_font_description(layout->pl, draw->desc);
- pango_layout_set_text(layout->pl, text, -1);
- pango_layout_set_alignment(layout->pl, PANGO_ALIGN_CENTER);
+ if (btn->simple) {
+ layout->pl = pango_cairo_create_layout(window_get_context(win));
+ layout_text(layout, draw->desc, scale, height, radius);
+ x += layout->width + line_w * 2;
+ } else {
+ ButtonGroup *group = CAST(btn, ButtonGroup);
+ layout->pl = NULL;
- int text_w, text_h;
- pango_layout_get_pixel_size(layout->pl, &text_w, &text_h);
+ g_assert_nonnull(group->children);
- layout->text_w = ceil(text_w / scale);
- layout->text_h = ceil(text_h / scale);
+ for (GList *it = group->children; it; it = it->next) {
+ Button *btn = it->data;
+ // Nested groups are not allowed
+ g_assert_true(btn->simple);
- // If there is only one glyph the button should be round
- size_t text_l = g_utf8_strlen(text, -1);
+ Layout *child = g_malloc(sizeof(Layout));
+ child->btn = btn;
- layout->width = text_l == 1 ? height : layout->text_w + 2 * radius;
- layout->height = height;
+ child->x = x;
+ child->y = 0;
- draw->layouts = g_list_prepend(draw->layouts, layout);
+ child->pl = pango_cairo_create_layout(window_get_context(win));
+ layout_text(child, draw->desc, scale, height, radius);
+
+ draw->layouts = g_list_prepend(draw->layouts, child);
- if (prev != NULL) {
- if (prev->align == btn->align) {
- x += sep;
- // Ugly update for layout
- layout->x = x;
- } else {
- if (btn->align == PANGO_ALIGN_CENTER) adjust_center = draw->layouts;
- else if (btn->align == PANGO_ALIGN_RIGHT) adjust_right = draw->layouts;
+ x += child->width + line_w * 2;
+
+ if (it->next != NULL) x += sep;
}
+
+ layout->width = x - layout->x;
+ layout->height = height;
+
+ // FIXME: Temporary solution to make the antialiasing (or the circles not overlapping correctly) problem less noticeable
+ layout->x += 1;
+ layout->width -= 2;
}
- x += layout->width + line_w * 2;
+ if (prev != NULL && prev->align != btn->align) {
+ if (btn->align == PANGO_ALIGN_CENTER) adjust_center = draw->layouts;
+ else if (btn->align == PANGO_ALIGN_RIGHT) adjust_right = draw->layouts;
+ }
prev = btn;
end_xs[btn->align] = x;