From 00bd74159e2f7d209a10d11e8cbecb894c3d0ef0 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sun, 26 Nov 2023 20:18:08 +0100 Subject: Generalize button struct --- src/button.c | 55 ++++++++++++++++++++++++++++++++++++++++---------- src/button.h | 43 ++++++++++++++++++++++++++++++--------- src/comet.c | 65 +++++++++++++++++++++++++++++------------------------------ src/connect.c | 20 ++++++++++-------- src/draw.c | 23 ++++++++++++--------- 5 files changed, 135 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/button.c b/src/button.c index 2f279d4..0ff1437 100644 --- a/src/button.c +++ b/src/button.c @@ -2,29 +2,62 @@ #include "button.h" -Button *button_create(const char *text, PangoAlignment align) +Button *button_simple_create(PangoAlignment align, Color color, Color line_color) { - Button *btn = g_malloc0(sizeof(Button)); - btn->text = g_strdup(text); + Button *btn = g_malloc0(sizeof(ButtonSimple)); + btn->simple = true; btn->align = align; + btn->color = color; + btn->line_color = line_color; return btn; } -void button_set_colors(Button *btn, Color background, Color foreground, Color stroke) +void button_simple_set_text(Button *btn, const char *text, Color text_color) { - btn->background = background; - btn->foreground = foreground; - btn->stroke = stroke; + g_assert(btn->simple); + ButtonSimple *sbtn = CAST(btn, ButtonSimple); + if (sbtn->text != NULL) g_free(sbtn->text); + sbtn->text = g_strdup(text); + sbtn->text_color = text_color; } -void button_set_action(Button *btn, ButtonAction action, gpointer data) +const char *button_simple_get_text(Button *btn) { - btn->action = action; - btn->action_data = data; + g_assert(btn->simple); + return CAST(btn, ButtonSimple)->text; +} + +void button_simple_set_action(Button *btn, ButtonAction action, gpointer data) +{ + g_assert(btn->simple); + CAST(btn, ButtonSimple)->action = action; + CAST(btn, ButtonSimple)->action_data = data; +} + +ButtonAction button_simple_get_action(Button *btn) +{ + g_assert(btn->simple); + return CAST(btn, ButtonSimple)->action; +} + +Button *button_group_create(PangoAlignment align, Color color, Color line_color) +{ + Button *btn = g_malloc0(sizeof(ButtonGroup)); + btn->simple = false; + btn->align = align; + btn->color = color; + btn->line_color = line_color; + return btn; +} + +void button_group_append(Button *btn, Button *child) +{ + g_assert(!btn->simple); + CAST(btn, ButtonGroup)->children = g_list_append(CAST(btn, ButtonGroup)->children, child); } void button_destroy(Button *btn) { - g_free(btn->text); + if (btn->simple) g_free(CAST(btn, ButtonSimple)->text); g_free(btn); } diff --git a/src/button.h b/src/button.h index f9406f1..aa22001 100644 --- a/src/button.h +++ b/src/button.h @@ -2,9 +2,11 @@ #define COMET_BUTTON_H #include +#include #include -// TODO: Generic button shapes/actions +// For pointers only +#define CAST(ptr, type) ((type *)ptr) typedef struct Button Button; @@ -15,20 +17,41 @@ typedef struct { } Color; struct Button { - ButtonAction action; - gpointer action_data; - char *text; + bool simple; PangoAlignment align; - Color background; - Color foreground; - Color stroke; + Color color; + Color line_color; }; -Button *button_create(const char *text, PangoAlignment align); +typedef struct { + Button btn; + Color text_color; + char *text; + ButtonAction action; + gpointer action_data; +} ButtonSimple; + +typedef struct { + Button btn; + GList *children; +} ButtonGroup; + +// NOTE: For the moment all button specific functions take a generic button +// pointer and assert the right type, so the check should be done by the caller + +Button *button_simple_create(PangoAlignment align, Color color, Color line_color); + +void button_simple_set_text(Button *btn, const char *text, Color text_color); + +const char *button_simple_get_text(Button *btn); + +void button_simple_set_action(Button *btn, ButtonAction action, gpointer data); + +ButtonAction button_simple_get_action(Button *btn); -void button_set_colors(Button *btn, Color background, Color foreground, Color stroke); +Button *button_group_create(PangoAlignment align, Color color, Color line_color); -void button_set_action(Button *btn, ButtonAction action, gpointer data); +void button_group_append(Button *btn, Button *child); void button_destroy(Button *btn); diff --git a/src/comet.c b/src/comet.c index 4b28a71..7664ade 100644 --- a/src/comet.c +++ b/src/comet.c @@ -39,7 +39,7 @@ static gboolean mainloop_quit(gpointer data) static gboolean disk_update(gpointer data) { - Button *btn = data; + ButtonSimple *btn = data; struct statvfs buffer; g_assert(statvfs("/", &buffer) == 0); @@ -59,7 +59,7 @@ static gboolean disk_update(gpointer data) static gboolean temp_update(gpointer data) { - Button *btn = data; + ButtonSimple *btn = data; FILE *temp = fopen("/sys/class/thermal/thermal_zone2/temp", "rb"); g_assert_nonnull(temp); @@ -110,7 +110,7 @@ char *cpu_percentage(void) static gboolean cpu_update(gpointer data) { - Button *btn = data; + ButtonSimple *btn = data; char *perc = cpu_percentage(); // Don't update on error @@ -130,7 +130,7 @@ static gboolean cpu_update(gpointer data) static gboolean ram_update(gpointer data) { - Button *btn = data; + ButtonSimple *btn = data; FILE *meminfo = fopen("/proc/meminfo", "rb"); g_assert_nonnull(meminfo); @@ -159,7 +159,7 @@ static gboolean ram_update(gpointer data) static gboolean date_update(gpointer data) { - Button *btn = data; + ButtonSimple *btn = data; size_t len1 = g_utf8_strlen(btn->text, -1); g_free(btn->text); @@ -191,13 +191,13 @@ static gboolean date_update(gpointer data) static void show_action(Button *btn) { - log_info("Called action: %s", btn->text); + log_info("Called action: %s", button_simple_get_text(btn)); } static void quit_action(Button *btn) { log_info("Quit button pressed"); - g_main_loop_quit(btn->action_data); + g_main_loop_quit(CAST(btn, ButtonSimple)->action_data); } int main(int argc, char **argv) @@ -226,45 +226,45 @@ int main(int argc, char **argv) State *state = state_create(win, draw); - Color background = { 0.4, 0.4, 0.4, 1 }; - Color foreground = { 0.8, 0.8, 0.8, 1 }; - Color stroke = { 0.8, 0.8, 0.8, 1 }; + Color color = { 0.4, 0.4, 0.4, 1 }; + Color line_color = { 0.8, 0.8, 0.8, 1 }; + Color text_color = { 0.8, 0.8, 0.8, 1 }; for (int i = 0; i < 9; ++i) { char text[] = { '1' + i, '\0' }; - Button *btn = button_create(text, PANGO_ALIGN_LEFT); - button_set_colors(btn, background, foreground, stroke); - button_set_action(btn, show_action, NULL); + Button *btn = button_simple_create(PANGO_ALIGN_LEFT, color, line_color); + button_simple_set_text(btn, text, text_color); + button_simple_set_action(btn, show_action, NULL); state_add_button(state, btn); } - Button *cpu_btn = button_create("cpu", PANGO_ALIGN_RIGHT); - button_set_colors(cpu_btn, background, foreground, stroke); - button_set_action(cpu_btn, show_action, state); + Button *cpu_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + button_simple_set_text(cpu_btn, "cpu", text_color); + button_simple_set_action(cpu_btn, show_action, state); state_add_button(state, cpu_btn); cpu_update(cpu_btn); g_timeout_add(1000, cpu_update, cpu_btn); - Button *temp_btn = button_create("temp", PANGO_ALIGN_RIGHT); - button_set_colors(temp_btn, background, foreground, stroke); - button_set_action(temp_btn, show_action, state); + Button *temp_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + button_simple_set_text(temp_btn, "temp", text_color); + button_simple_set_action(temp_btn, show_action, state); state_add_button(state, temp_btn); temp_update(temp_btn); g_timeout_add(20 * 1000, temp_update, temp_btn); - Button *ram_btn = button_create("ram", PANGO_ALIGN_RIGHT); - button_set_colors(ram_btn, background, foreground, stroke); - button_set_action(ram_btn, show_action, state); + Button *ram_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + button_simple_set_text(ram_btn, "ram", text_color); + button_simple_set_action(ram_btn, show_action, state); state_add_button(state, ram_btn); ram_update(ram_btn); g_timeout_add(10 * 1000, ram_update, ram_btn); - Button *disk_btn = button_create("disk", PANGO_ALIGN_RIGHT); - button_set_colors(disk_btn, background, foreground, stroke); - button_set_action(disk_btn, show_action, state); + Button *disk_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + button_simple_set_text(disk_btn, "disk", text_color); + button_simple_set_action(disk_btn, show_action, state); state_add_button(state, disk_btn); disk_update(disk_btn); @@ -275,9 +275,9 @@ int main(int argc, char **argv) timer_t timer; } date_ctx = { state, 0 }; - Button *date_btn = button_create("date", PANGO_ALIGN_CENTER); - button_set_colors(date_btn, background, foreground, stroke); - button_set_action(date_btn, show_action, &date_ctx); + Button *date_btn = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + button_simple_set_text(date_btn, "date", text_color); + button_simple_set_action(date_btn, show_action, &date_ctx); state_add_button(state, date_btn); struct sigevent sev = { 0 }; @@ -287,11 +287,10 @@ int main(int argc, char **argv) g_assert(timer_create(CLOCK_REALTIME, &sev, &date_ctx.timer) == 0); date_update(date_btn); - // purple - Color background2 = { 0.502, 0.168, 0.886, 1 }; - Button *q_btn = button_create("", PANGO_ALIGN_RIGHT); - button_set_colors(q_btn, background2, foreground, stroke); - button_set_action(q_btn, quit_action, mainloop); + Color purple = { 0.502, 0.168, 0.886, 1 }; + Button *q_btn = button_simple_create(PANGO_ALIGN_RIGHT, purple, line_color); + button_simple_set_text(q_btn, "", text_color); + button_simple_set_action(q_btn, quit_action, mainloop); state_add_button(state, q_btn); connect_attach_state(con, state); diff --git a/src/connect.c b/src/connect.c index 12038a4..24f6463 100644 --- a/src/connect.c +++ b/src/connect.c @@ -88,15 +88,19 @@ static void button_action(State *state, const char *event, int x, int y) if (layout->x + layout->width < x) continue; if (layout->x > x) break; - log_debug("Button layout [x=%d, y=%d, w=%d, h=%d]", - layout->x, layout->y, layout->width, layout->height); - - if (in_capsule(x, y, layout->x, layout->y, layout->width, layout->height)) { - log_debug("Triggering action for button"); - if (layout->btn->action != NULL) { - layout->btn->action(layout->btn); + if (layout->btn->simple) { + log_debug("Button layout [x=%d, y=%d, w=%d, h=%d]", + layout->x, layout->y, layout->width, layout->height); + + if (in_capsule(x, y, layout->x, layout->y, layout->width, layout->height)) { + log_debug("Triggering action for button"); + ButtonAction action = button_simple_get_action(layout->btn); + if (action != NULL) action(layout->btn); + return; } - return; + } else { + log_debug("Button group layout [x=%d, y=%d, w=%d, h=%d]", + layout->x, layout->y, layout->width, layout->height); } } diff --git a/src/draw.c b/src/draw.c index 42c22bd..8bf190f 100644 --- a/src/draw.c +++ b/src/draw.c @@ -90,7 +90,7 @@ void draw_paint(Drawable *draw, Window *win) 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->background; + Color color = layout->btn->color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); cairo_new_sub_path(cr); cairo_arc(cr, layout->x + radius, layout->y + radius, radius, 90 * degree, 270 * degree); @@ -98,7 +98,7 @@ void draw_paint(Drawable *draw, Window *win) cairo_close_path(cr); cairo_fill(cr); - color = layout->btn->stroke; + color = layout->btn->line_color; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); cairo_new_sub_path(cr); cairo_arc(cr, layout->x + radius, layout->y + radius, radius - line_w , 90 * degree, 270 * degree); @@ -106,12 +106,14 @@ void draw_paint(Drawable *draw, Window *win) cairo_close_path(cr); cairo_stroke(cr); - color = layout->btn->foreground; - cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); - cairo_move_to(cr, text_x, text_y); + if (layout->btn->simple) { + color = ((ButtonSimple *)layout->btn)->text_color; + cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); + cairo_move_to(cr, text_x, text_y); - pango_cairo_update_layout(cr, layout->pl); - pango_cairo_show_layout(cr, layout->pl); + pango_cairo_update_layout(cr, layout->pl); + pango_cairo_show_layout(cr, layout->pl); + } } cairo_destroy(cr); @@ -169,9 +171,12 @@ void draw_compute_layout(Drawable *draw, Window *win, GList *btns) layout->x = x; layout->y = 0; + //FIXME + const char *text = btn->simple ? ((ButtonSimple *)btn)->text : "x"; + 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, btn->text, -1); + pango_layout_set_text(layout->pl, text, -1); pango_layout_set_alignment(layout->pl, PANGO_ALIGN_CENTER); int text_w, text_h; @@ -181,7 +186,7 @@ void draw_compute_layout(Drawable *draw, Window *win, GList *btns) 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(btn->text, -1); + size_t text_l = g_utf8_strlen(text, -1); layout->width = text_l == 1 ? height : layout->text_w + 2 * radius; layout->height = height; -- cgit v1.2.3