aboutsummaryrefslogtreecommitdiff
path: root/src/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/draw.c')
-rw-r--r--src/draw.c107
1 files changed, 94 insertions, 13 deletions
diff --git a/src/draw.c b/src/draw.c
index 91ae186..310bca9 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -41,18 +41,27 @@ Drawable *draw_create(const char *font, int height, int left_pad, int right_pad,
return draw;
}
-void draw_paint(Drawable *draw, Window *win)
+static void compute_width(Drawable *draw, Window *win, int *width, int *height)
{
// FIXME: Does not work for scale != 1
//double scale = window_get_scale(win);
double scale = 1;
- int screen_width, screen_height;
- window_get_screen_size(win, &screen_width, &screen_height);
+ int screen_width = win->con->screen_size->width;
+ int screen_height = win->con->screen_size->height;
+
+ *width = round(screen_width - draw->right_pad - draw->left_pad * scale);
+ *height = round(draw->height * scale);
+}
+
+void draw_paint(Drawable *draw, Window *win)
+{
+ // FIXME: Does not work for scale != 1
+ //double scale = window_get_scale(win);
+ double scale = 1;
- int width0 = screen_width - draw->right_pad - draw->left_pad;
- int width = round(width0 * scale);
- int height = round(draw->height * scale);
+ int width, height;
+ compute_width(draw, win, &width, &height);
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
@@ -112,13 +121,23 @@ void draw_paint(Drawable *draw, Window *win)
// TODO: Move these somewhere else
window_move(win, draw->left_pad, draw->top_pad);
- window_resize(win, width0, draw->height);
+ window_resize(win, width, draw->height);
window_paint_surface(win, surface, width, height);
cairo_surface_destroy(surface);
}
-void draw_compute_layout(Drawable *draw, GList *btns, cairo_t *cr)
+static gint align_compare(gconstpointer a, gconstpointer b)
+{
+ PangoAlignment a_align = ((Button *)a)->align;
+ PangoAlignment b_align = ((Button *)b)->align;
+
+ if (a_align < b_align) return -1;
+ if (a_align > b_align) return 1;
+ return 0;
+}
+
+void draw_compute_layout(Drawable *draw, Window *win, GList *btns)
{
g_list_free_full(draw->layouts, (GDestroyNotify)layout_destroy);
draw->layouts = NULL;
@@ -127,20 +146,31 @@ void draw_compute_layout(Drawable *draw, GList *btns, cairo_t *cr)
//double scale = window_get_scale(win);
double scale = 1;
+ int width, height;
+ compute_width(draw, win, &width, &height);
+
int x = 0;
- int height = round(draw->height * scale);
int radius = height / 2;
+ btns = g_list_sort(btns, align_compare);
+
+ GList *adjust_center = NULL;
+ GList *adjust_right = NULL;
+
+ int end_xs[3] = { 0 };
+ Button *prev = NULL;
+
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);
+ 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_alignment(layout->pl, PANGO_ALIGN_CENTER);
@@ -157,14 +187,65 @@ void draw_compute_layout(Drawable *draw, GList *btns, cairo_t *cr)
layout->width = text_l == 1 ? height : layout->text_w + 2 * radius;
layout->height = height;
- draw->layouts = g_list_append(draw->layouts, layout);
+ draw->layouts = g_list_prepend(draw->layouts, layout);
+
+ if (prev != NULL) {
+ if (prev->align == btn->align) {
+ int sep = 10 * scale;
+ 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;
+ }
+ }
- int sep = 10 * scale;
int line_w = 1 * scale;
- x += height + line_w * 2 + sep;
+ x += layout->width + line_w * 2;
+
+ prev = btn;
+ end_xs[btn->align] = x;
+ }
+
+ draw->layouts = g_list_reverse(draw->layouts);
+
+ int widths[3] = {
+ end_xs[0],
+ end_xs[1] - end_xs[0],
+ end_xs[2] - MAX(end_xs[1], end_xs[0]),
+ };
+
+ int start_xs[3] = {
+ 0,
+ end_xs[0],
+ MAX(end_xs[1], end_xs[0]),
+ };
+
+ log_info("e1 = %d, e2 = %d, e3 = %d", end_xs[0], end_xs[1], end_xs[2]);
+ log_info("s1 = %d, s2 = %d, s3 = %d", start_xs[0], start_xs[1], start_xs[2]);
+ log_info("w1 = %d, w2 = %d, w3 = %d", widths[0], widths[1], widths[2]);
+
+ int center = round(width / 2);
+ int center_off = (center - widths[1] / 2) - start_xs[1];
+ log_debug("Aligning center layout [x=%d, off=%d]", center, center_off);
+
+ for (GList *it = adjust_center; it != adjust_right; it = it->next) {
+ Layout *layout = it->data;
+ layout->x += center_off;
+ }
+
+ int right = width - widths[2];
+ int right_off = right - start_xs[2];
+ log_debug("Aligning right layout [x=%d, off=%d]", right, right_off);
+
+ for (GList *it = adjust_right; it != NULL; it = it->next) {
+ Layout *layout = it->data;
+ layout->x += right_off;
}
log_debug("Updated layouts");
+ g_list_free(btns);
}
void draw_destroy(Drawable *draw)