From 1deadc4ac7901e1bc8f2047df580e1c14d7a0144 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Fri, 15 Mar 2024 20:38:34 +0100 Subject: Start reworking draw_paint and add per-button line width --- src/button.c | 12 ++++--- src/button.h | 10 ++++-- src/comet.c | 32 +++++++++---------- src/connect.c | 2 +- src/draw.c | 100 ++++++++++++++++++++++++++++++++++------------------------ src/draw.h | 5 +-- src/dwm.c | 6 ++-- src/dwm.h | 2 +- 8 files changed, 97 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/button.c b/src/button.c index 2a74df6..5039364 100644 --- a/src/button.c +++ b/src/button.c @@ -3,13 +3,12 @@ #include "button.h" #include "log.h" -Button *button_simple_create(PangoAlignment align, Color color, Color line_color) +Button *button_simple_create(PangoAlignment align, Color color) { Button *btn = g_malloc0(sizeof(ButtonSimple)); btn->simple = true; btn->align = align; btn->color = color; - btn->line_color = line_color; CAST(btn, ButtonSimple)->action = NULL; return btn; } @@ -42,13 +41,12 @@ ButtonAction button_simple_get_action(Button *btn) return CAST(btn, ButtonSimple)->action; } -Button *button_group_create(PangoAlignment align, Color color, Color line_color) +Button *button_group_create(PangoAlignment align, Color color) { Button *btn = g_malloc0(sizeof(ButtonGroup)); btn->simple = false; btn->align = align; btn->color = color; - btn->line_color = line_color; return btn; } @@ -74,6 +72,12 @@ bool button_set_animation(Button *btn, Animation *anim) return true; } +void button_set_line(Button *btn, Color line_color, int line_width) +{ + btn->line_color = line_color; + btn->line_width = line_width; +} + void button_destroy(Button *btn) { if (btn->simple) g_free(CAST(btn, ButtonSimple)->text); diff --git a/src/button.h b/src/button.h index 7ebf435..57907b4 100644 --- a/src/button.h +++ b/src/button.h @@ -17,10 +17,12 @@ typedef void (* ButtonAction)(Button *btn); struct Button { bool simple; - int x_pad, y_pad; + int x_pad; + int y_pad; PangoAlignment align; Color color; Color line_color; + int line_width; Animation *anim; }; @@ -40,7 +42,7 @@ typedef struct { // 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); +Button *button_simple_create(PangoAlignment align, Color color); // Takes ownership of text void button_simple_set_text(Button *btn, char *text, Color text_color); @@ -51,7 +53,7 @@ void button_simple_set_action(Button *btn, ButtonAction action, gpointer data); ButtonAction button_simple_get_action(Button *btn); -Button *button_group_create(PangoAlignment align, Color color, Color line_color); +Button *button_group_create(PangoAlignment align, Color color); void button_group_append(Button *btn, Button *child); @@ -59,6 +61,8 @@ void button_set_padding(Button *btn, int x_pad, int y_pad); bool button_set_animation(Button *btn, Animation *anim); +void button_set_line(Button *btn, Color line_color, int line_width); + void button_destroy(Button *btn); #endif diff --git a/src/comet.c b/src/comet.c index ed2ea91..617fcb5 100644 --- a/src/comet.c +++ b/src/comet.c @@ -220,10 +220,10 @@ static void menu_action(Button *btn) state_request_redraw(menu_ctx->state, true); } -static void register_buttons(State *state, Color color, Color line_color, Color text_color) +static void register_buttons(State *state, Color color, Color text_color) { // Cpu usage button - Button *cpu_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + Button *cpu_btn = button_simple_create(PANGO_ALIGN_RIGHT, color); button_simple_set_text(cpu_btn, g_strdup(" 0%"), text_color); button_simple_set_action(cpu_btn, show_action, state); state_add_button(state, cpu_btn); @@ -232,7 +232,7 @@ static void register_buttons(State *state, Color color, Color line_color, Color g_timeout_add(1000, cpu_update, cpu_btn); // Temperature button - Button *temp_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + Button *temp_btn = button_simple_create(PANGO_ALIGN_RIGHT, color); button_simple_set_text(temp_btn, g_strdup("temp"), text_color); button_simple_set_action(temp_btn, show_action, state); state_add_button(state, temp_btn); @@ -241,7 +241,7 @@ static void register_buttons(State *state, Color color, Color line_color, Color g_timeout_add(20 * 1000, temp_update, temp_btn); // Ram usage button - Button *ram_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + Button *ram_btn = button_simple_create(PANGO_ALIGN_RIGHT, color); button_simple_set_text(ram_btn, g_strdup("ram"), text_color); button_simple_set_action(ram_btn, show_action, state); state_add_button(state, ram_btn); @@ -250,7 +250,7 @@ static void register_buttons(State *state, Color color, Color line_color, Color g_timeout_add(10 * 1000, ram_update, ram_btn); // Disk usage button - Button *disk_btn = button_simple_create(PANGO_ALIGN_RIGHT, color, line_color); + Button *disk_btn = button_simple_create(PANGO_ALIGN_RIGHT, color); button_simple_set_text(disk_btn, g_strdup("disk"), text_color); button_simple_set_action(disk_btn, show_action, state); state_add_button(state, disk_btn); @@ -280,21 +280,21 @@ int main(int argc, char **argv) log_debug("Calculated dimensions [height=%d, x_pad=%d, y_pad=%d]", height, x_padding, y_padding); Color background_all = { 0.3, 0.3, 0.3, 1 }; - Drawer *draw = draw_create("Hack 13 Bold", height, x_padding, x_padding, y_padding, 0); + Drawer *draw = draw_create("Hack 13 Bold", height, x_padding, x_padding, y_padding); draw_set_background(draw, background_all); State *state = state_create(win, draw); Color color = { 0.4, 0.4, 0.4, 1 }; Color purple = { 0.502, 0.168, 0.886, 1 }; - Color line_color = { 0.8, 0.8, 0.8, 1 }; + //Color line_color = { 0.8, 0.8, 0.8, 1 }; Color text_color = { 0.9, 0.9, 0.9, 1 }; // Dwm tags DwmIpc *dwm = dwm_create(state, "/tmp/dwm.sock"); - dwm_register_tags(dwm, color, purple, text_color, line_color); + dwm_register_tags(dwm, color, purple, text_color); - register_buttons(state, color, line_color, text_color); + register_buttons(state, color, text_color); // Buttons with special handling @@ -304,7 +304,7 @@ int main(int argc, char **argv) } date_ctx = { state, 0 }; // Date & time button - Button *date_btn = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + Button *date_btn = button_simple_create(PANGO_ALIGN_CENTER, color); button_simple_set_text(date_btn, g_strdup("date"), text_color); button_simple_set_action(date_btn, NULL, &date_ctx); state_add_button(state, date_btn); @@ -317,26 +317,26 @@ int main(int argc, char **argv) date_update(date_btn); // Quit button - Button *q_btn = button_simple_create(PANGO_ALIGN_RIGHT, purple, line_color); + Button *q_btn = button_simple_create(PANGO_ALIGN_RIGHT, purple); button_simple_set_text(q_btn, g_strdup(""), text_color); button_simple_set_action(q_btn, quit_action, mainloop); state_add_button(state, q_btn); // Menu button(s) Color grey = { 0.5, 0.5, 0.5, 1 }; - Button *group = button_group_create(PANGO_ALIGN_LEFT, grey, line_color); + Button *group = button_group_create(PANGO_ALIGN_LEFT, grey); - Button *child1 = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + Button *child1 = button_simple_create(PANGO_ALIGN_CENTER, color); button_set_padding(child1, 1, 1); button_simple_set_text(child1, g_strdup("C1"), text_color); button_simple_set_action(child1, show_action, NULL); - Button *child2 = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + Button *child2 = button_simple_create(PANGO_ALIGN_CENTER, color); button_set_padding(child2, 1, 1); button_simple_set_text(child2, g_strdup("C2"), text_color); button_simple_set_action(child2, show_action, NULL); - Button *child3 = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + Button *child3 = button_simple_create(PANGO_ALIGN_CENTER, color); button_set_padding(child3, 1, 1); button_simple_set_text(child3, g_strdup("C3"), text_color); button_simple_set_action(child3, show_action, NULL); @@ -348,7 +348,7 @@ int main(int argc, char **argv) State *state; } menu_ctx = { (gpointer)group, {"", ""}, NULL, state }; - Button *menu = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + Button *menu = button_simple_create(PANGO_ALIGN_CENTER, color); button_simple_set_text(menu, g_strdup(menu_ctx.strings[0]), text_color); button_simple_set_action(menu, menu_action, &menu_ctx); diff --git a/src/connect.c b/src/connect.c index 274421b..97deca5 100644 --- a/src/connect.c +++ b/src/connect.c @@ -102,7 +102,7 @@ static void button_action(State *state, const char *event, int x, int y) if (action != NULL) { // NOTE: Animations may change layout! //Animation *anim = animation_shine_create(300 * G_TIME_SPAN_MILLISECOND); - Animation *anim = animation_pulse_create(300 * G_TIME_SPAN_MILLISECOND); + Animation *anim = animation_pulse_create(200 * G_TIME_SPAN_MILLISECOND); if (button_set_animation(btn, anim)) state_request_animation(state); diff --git a/src/draw.c b/src/draw.c index 2bdcdf2..b9b140c 100644 --- a/src/draw.c +++ b/src/draw.c @@ -11,10 +11,11 @@ static void layout_destroy(Layout *layout) { if (layout->pl != NULL) g_object_unref(layout->pl); + g_list_free_full(layout->children, (GDestroyNotify)layout_destroy); g_free(layout); } -Drawer *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad, int line_w) +Drawer *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad) { Drawer *draw = g_malloc(sizeof(Drawer)); g_assert_nonnull(draw); @@ -28,10 +29,10 @@ Drawer *draw_create(const char *font, int height, int left_pad, int right_pad, i draw->right_pad = right_pad; draw->top_pad = top_pad; - draw->line_w = line_w; draw->layouts = NULL; - log_debug("Draw context created [height=%d, left_pad=%d, right_pad=%d, top_pad=%d, line_w=%d]", height, left_pad, right_pad, top_pad, line_w); + log_debug("Draw context created [height=%d, left_pad=%d, right_pad=%d, top_pad=%d]", + height, left_pad, right_pad, top_pad); return draw; } @@ -46,6 +47,45 @@ static void compute_width(Drawer *draw, Window *win, int *width, int *height) *height = round(draw->height); } +static void paint_button(cairo_t *cr, const Layout *layout) +{ + double degree = M_PI / 180.0; + int radius = (layout->height - 2 * layout->y_pad) / 2; + + cairo_set_line_width(cr, layout->line_w); + + 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 + layout->x_pad + radius, layout->y + layout->y_pad + radius, radius, 90 * degree, 270 * degree); + cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, radius, 270 * degree, 450 * degree); + cairo_close_path(cr); + cairo_fill(cr); + + 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 + layout->x_pad + radius, layout->y + layout->y_pad + radius, radius - layout->line_w, 90 * degree, 270 * degree); + cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, radius - layout->line_w, 270 * degree, 450 * degree); + cairo_close_path(cr); + cairo_stroke(cr); +} + +static void paint_text(cairo_t *cr, const Layout *layout) +{ + 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 = 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); + + // NOTE: This works only if the text didn't change in size after the layouting + pango_layout_set_text(layout->pl, CAST(layout->btn, ButtonSimple)->text, -1); + pango_cairo_update_layout(cr, layout->pl); + pango_cairo_show_layout(cr, layout->pl); +} + void draw_paint(Drawer *draw, Window *win) { int width, height; @@ -57,51 +97,22 @@ void draw_paint(Drawer *draw, Window *win) cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - double degree = M_PI / 180.0; - // Fill the background cairo_set_source_rgba(cr, draw->background.r, draw->background.g, draw->background.b, draw->background.a); cairo_paint(cr); - int line_w = draw->line_w; - cairo_set_line_width(cr, line_w); - for (GList *it = draw->layouts; it; it = it->next) { Layout *layout = it->data; Button *btn = layout->btn; cairo_push_group(cr); - int radius = (layout->height - 2 * layout->y_pad) / 2; - - Color color = 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 + layout->x_pad + radius, layout->y + layout->y_pad + radius, radius, 90 * degree, 270 * degree); - cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, radius, 270 * degree, 450 * degree); - cairo_close_path(cr); - cairo_fill(cr); - - color = 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 + layout->x_pad + radius, layout->y + layout->y_pad + radius, radius - line_w, 90 * degree, 270 * degree); - cairo_arc(cr, layout->x + layout->width - layout->x_pad - radius, layout->y + layout->y_pad + radius, radius - line_w, 270 * degree, 450 * degree); - cairo_close_path(cr); - cairo_stroke(cr); + paint_button(cr, layout); if (btn->simple) { - int text_x = layout->x + layout->width / 2 - layout->text_w / 2; - int text_y = layout->y + layout->y_pad + radius - layout->text_h / 2; - - color = CAST(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); - - // NOTE: This works only if the text didn't change in size after the layouting - pango_layout_set_text(layout->pl, CAST(btn, ButtonSimple)->text, -1); - pango_cairo_update_layout(cr, layout->pl); - pango_cairo_show_layout(cr, layout->pl); + paint_text(cr, layout); + } else { + // TODO } if (btn->anim != NULL && btn->anim->paint_func != NULL) { @@ -163,9 +174,7 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) int x = 0; int radius = height / 2; - int sep = 10; - int line_w = draw->line_w; GList *layout_start[3] = { NULL }; int layout_end[3] = { 0 }; @@ -175,9 +184,11 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) Layout *layout = g_malloc(sizeof(Layout)); layout->btn = btn; + layout->children = NULL; if (prev != NULL && prev->align == btn->align) x += sep; + layout->line_w = btn->line_width; layout->x_pad = btn->x_pad; layout->y_pad = btn->y_pad; @@ -207,6 +218,8 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) Layout *child = g_malloc(sizeof(Layout)); child->btn = btn; + child->children = NULL; + child->line_w = btn->line_width; child->x_pad = btn->x_pad; child->y_pad = btn->y_pad; @@ -219,7 +232,7 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) draw->layouts = g_list_prepend(draw->layouts, child); - x += child->width + line_w * 2; + x += child->width + child->line_w * 2; if (it->next != NULL) x += sep; } @@ -256,7 +269,7 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) btn->anim->layout_func = NULL; } - x += layout->width + line_w * 2; + x += layout->width + layout->line_w * 2; } prev = btn; @@ -284,9 +297,12 @@ void draw_compute_layout(Drawer *draw, Window *win, GList *btns) layout->x += center_off; } - int right = width - layout_width[PANGO_ALIGN_RIGHT]; // The width is off by 2 line width - int right_off = right - MAX(layout_end[PANGO_ALIGN_LEFT], layout_end[PANGO_ALIGN_CENTER]) + 2 * line_w; + int first_line_w = CAST(layout_start[PANGO_ALIGN_RIGHT]->data, Layout)->line_w; + int last_line_w = CAST(g_list_last(layout_start[PANGO_ALIGN_RIGHT])->data, Layout)->line_w; + + int right = width - layout_width[PANGO_ALIGN_RIGHT]; + int right_off = right - MAX(layout_end[PANGO_ALIGN_LEFT], layout_end[PANGO_ALIGN_CENTER]) + first_line_w + last_line_w; log_debug("Aligning right layout [x=%d, off=%d]", right, right_off); for (GList *it = layout_start[PANGO_ALIGN_RIGHT]; it != NULL; it = it->next) { diff --git a/src/draw.h b/src/draw.h index db56946..f68b4ab 100644 --- a/src/draw.h +++ b/src/draw.h @@ -19,7 +19,6 @@ typedef struct { int left_pad; int right_pad; int top_pad; - int line_w; Color background; GList *layouts; } Drawer; @@ -30,10 +29,12 @@ typedef struct { int width, height; int text_w, text_h; int x_pad, y_pad; + int line_w; PangoLayout *pl; + GList *children; } Layout; -Drawer *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad, int line_w); +Drawer *draw_create(const char *font, int height, int left_pad, int right_pad, int top_pad); void draw_compute_layout(Drawer *draw, Window *win, GList *btns); diff --git a/src/dwm.c b/src/dwm.c index a2bf764..87d794e 100644 --- a/src/dwm.c +++ b/src/dwm.c @@ -398,7 +398,7 @@ static void change_tag_action(Button *btn) ipc_run_command(dwm, "view", args); } -void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color, Color line_color) +void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color) { if (dwm == NULL) return; @@ -409,7 +409,7 @@ void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_colo // Tags button for (int i = 0; i < 9; ++i) { char text[] = { '1' + i, '\0' }; - dwm->tags[i] = button_simple_create(PANGO_ALIGN_LEFT, color, line_color); + dwm->tags[i] = button_simple_create(PANGO_ALIGN_LEFT, color); button_simple_set_text(dwm->tags[i], g_strdup(text), text_color); button_simple_set_action(dwm->tags[i], change_tag_action, dwm); state_add_button(dwm->state, dwm->tags[i]); @@ -418,7 +418,7 @@ void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_colo // This will set the tag names ipc_get_tags(dwm); - dwm->title = button_simple_create(PANGO_ALIGN_CENTER, color, line_color); + dwm->title = button_simple_create(PANGO_ALIGN_CENTER, color); dwm->hidden_title = true; // FIXME: Set the first tag diff --git a/src/dwm.h b/src/dwm.h index 566360f..2ce055c 100644 --- a/src/dwm.h +++ b/src/dwm.h @@ -21,7 +21,7 @@ typedef struct { DwmIpc *dwm_create(State *state, const char *socket); -void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color, Color line_color); +void dwm_register_tags(DwmIpc *dwm, Color color, Color selected, Color text_color); void dwm_destroy(DwmIpc *dwm); -- cgit v1.2.3