aboutsummaryrefslogtreecommitdiff
path: root/src/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/draw.c')
-rw-r--r--src/draw.c100
1 files changed, 58 insertions, 42 deletions
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) {