From 07646612acbc833ec50479eee3564af37636f272 Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sun, 19 Nov 2023 01:32:37 +0100 Subject: Check button clicks and trigger actions --- src/connect.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'src/connect.c') diff --git a/src/connect.c b/src/connect.c index 9272a5c..bc45812 100644 --- a/src/connect.c +++ b/src/connect.c @@ -48,6 +48,62 @@ static void update_scale(Connection *con) } } +static inline bool in_rect(int px, int py, int x, int y, int w, int h) +{ + return px >= x && px <= x + w && py >= y && py <= y + h; +} + +static inline bool in_circle(int px, int py, int x, int y, int r) +{ + int dx = x - px; + int dy = y - py; + return (dx * dx + dy * dy) <= r * r; +} + +static inline bool in_capsule(int px, int py, int x, int y, int w, int h) +{ + g_assert(w >= h); + int radius = h / 2; + + // Circle case + if (w == h) return in_circle(px, py, x + radius, y + radius, radius); + + // Capsule case + return in_circle(px, py, x + radius, y + radius, radius) + || in_circle(px, py, x + w - radius, y + radius, radius) + || in_rect(px, py, x + radius, y, w - 2 * radius, h); +} + +static void button_action(State *state, xcb_button_release_event_t *button) +{ + log_debug("Button release event [x=%d, y=%d]", button->event_x, button->event_y); + + for (GList *it = state->draw->layouts; it != NULL; it = it->next) { + Layout *layout = it->data; + + // Skip + if (layout->x + layout->width < button->event_x) continue; + if (layout->x > button->event_x) break; + + bool check = in_capsule(button->event_x, button->event_y, + layout->x, layout->y, + layout->width, layout->height); + + log_debug("Button layout [x=%d, y=%d, w=%d, h=%d]", + layout->x, layout->y, layout->width, layout->height); + + if (check) { + log_debug("Triggering action for button"); + if (layout->btn->action != NULL) { + layout->btn->action(layout->btn); + } + return; + } + } + + log_debug("Ignoring button release"); +} + typedef struct { GSource source; Connection *con; @@ -115,9 +171,21 @@ static gboolean source_dispatch(GSource *source, GSourceFunc callback, gpointer } case XCB_BUTTON_RELEASE: { - log_debug("Mouse event"); - - // TODO: Handle click generically by translating the button code + xcb_button_release_event_t *button = (xcb_button_release_event_t *)xsource->event; + log_debug("Processing event 'ButtonRelease' [type=%d]", XCB_BUTTON_RELEASE); + + // TODO: Handle different actions properly + switch (button->detail) { + case XCB_BUTTON_INDEX_2: // left click + case XCB_BUTTON_INDEX_1: // right click + case XCB_BUTTON_INDEX_3: // middle click + button_action(xsource->con->state, button); + break; + + default: + log_debug("Ignoring button release [button=%d]", button->detail); + break; + } break; } -- cgit v1.2.3