From 6e5087293397ff3fb9e4de2d8e5bd7e4d7ec1984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 23 Sep 2019 18:34:43 +0200 Subject: [PATCH] particle/progress-bar: improve accuracy of 'where' tag The progress-bar took *all* particle elements into account when calculating the (relative) mouse position on mouse events. This is wrong, since only the progress bar (that is, the empty and filled cells) should be used. Not the start/end elements. We now also pass the mouse event through to the start/end elements. --- particles/progress-bar.c | 48 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/particles/progress-bar.c b/particles/progress-bar.c index e4e1715..06e53b2 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -103,13 +103,52 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, * * Keep a reference to the un-expanded string, to be able to reset * it after executing the handler. + * + * Note that we only consider the actual progress bar to be + * clickable. This means we ignore the start and end markers. */ - char *original = exposable->on_click; + const struct particle *p = exposable->particle; + const struct eprivate *e = exposable->private; - assert(x >= 0 && x < exposable->width); - long where = exposable->width > 0 - ? 100 * x / exposable->width + /* Start of empty/fill cells */ + int x_offset = p->left_margin + e->exposables[0]->width; + + /* Mouse is *before* progress-bar? */ + if (x < x_offset) { + if (x >= p->left_margin) { + /* Mouse is over the start-marker */ + struct exposable *start = e->exposables[0]; + if (start->on_mouse != NULL) + start->on_mouse(start, bar, event, x - p->left_margin, y); + } else { + /* Mouse if over left margin */ + bar->set_cursor(bar, "left_ptr"); + } + return; + } + + /* Size of the clickable area (the empty/fill cells) */ + int clickable_width = 0; + for (size_t i = 1; i < e->count - 1; i++) + clickable_width += e->exposables[i]->width; + + /* Mouse is *after* progress-bar? */ + if (x - x_offset > clickable_width) { + if (x - x_offset - clickable_width < e->exposables[e->count - 1]->width) { + /* Mouse is over the end-marker */ + struct exposable *end = e->exposables[e->count - 1]; + if (end->on_mouse != NULL) + end->on_mouse(end, bar, event, x - x_offset - clickable_width, y); + } else { + /* Mouse is over the right margin */ + bar->set_cursor(bar, "left_ptr"); + } + return; + } + + long where = clickable_width > 0 + ? 100 * (x - x_offset) / clickable_width : 0; struct tag_set tags = { @@ -117,6 +156,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, .count = 1, }; + char *original = exposable->on_click; exposable->on_click = tags_expand_template(exposable->on_click, &tags); tag_set_destroy(&tags);