From: Michael D. Lowis Date: Sun, 9 Oct 2016 03:57:04 +0000 (-0400) Subject: added detection for double and triple mouse clicks X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=8409a10ba555d923deb36bb849d626849cbc6289;p=projs%2Ftide.git added detection for double and triple mouse clicks --- diff --git a/mouse.c b/mouse.c index 556bdef..fcde885 100644 --- a/mouse.c +++ b/mouse.c @@ -1,20 +1,110 @@ #include "edit.h" +struct { + uint32_t time; + uint32_t count; +} Buttons[5] = { {0,0}, {0,0}, {0,0} }; + extern Buf Buffer; extern unsigned CursorPos; +#ifndef __MACH__ +#include +#else +#include +#define CLOCK_MONOTONIC 0 +// clock_gettime is not implemented on OSX +int clock_gettime(int id, struct timespec* t) { + (void)id; + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) return rv; + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; +} +#endif + +uint32_t getmillis(void) { + struct timespec time; + clock_gettime(CLOCK_MONOTONIC, &time); + return ((time.tv_sec * 1000) + (time.tv_nsec / 1000000)); +} + +/*****************************************************************************/ + +enum { + SINGLE_CLICK = 0, + DOUBLE_CLICK, + TRIPLE_CLICK +}; + +void unused(MouseEvent* mevnt) { + (void)mevnt; +} + +void move_cursor(MouseEvent* mevnt) { + CursorPos = screen_getoff(&Buffer, CursorPos, mevnt->y, mevnt->x); +} + +void select_word(MouseEvent* mevnt) { + (void)mevnt; +} + +void select_line(MouseEvent* mevnt) { + (void)mevnt; +} + +void scrollup(MouseEvent* mevnt) { + (void)mevnt; + CursorPos = buf_byline(&Buffer, CursorPos, -ScrollLines); +} + +void scrolldn(MouseEvent* mevnt) { + (void)mevnt; + CursorPos = buf_byline(&Buffer, CursorPos, ScrollLines); +} + +void (*Actions[5][3])(MouseEvent* mevnt) = { + [MOUSE_LEFT] = { + [SINGLE_CLICK] = move_cursor, + [DOUBLE_CLICK] = select_word, + [TRIPLE_CLICK] = select_line, + }, + [MOUSE_MIDDLE] = { + [SINGLE_CLICK] = unused, + [DOUBLE_CLICK] = unused, + [TRIPLE_CLICK] = unused, + }, + [MOUSE_RIGHT] = { + [SINGLE_CLICK] = unused, + [DOUBLE_CLICK] = unused, + [TRIPLE_CLICK] = unused, + }, + [MOUSE_WHEELUP] = { + [SINGLE_CLICK] = scrollup, + [DOUBLE_CLICK] = scrollup, + [TRIPLE_CLICK] = scrollup, + }, + [MOUSE_WHEELDOWN] = { + [SINGLE_CLICK] = scrolldn, + [DOUBLE_CLICK] = scrolldn, + [TRIPLE_CLICK] = scrolldn, + }, +}; + void handle_mouse(MouseEvent* mevnt) { - switch (mevnt->button) { - case MOUSE_LEFT: - CursorPos = screen_getoff(&Buffer, CursorPos, mevnt->y, mevnt->x); - break; - case MOUSE_WHEELUP: - CursorPos = buf_byline(&Buffer, CursorPos, -ScrollLines); - break; - case MOUSE_WHEELDOWN: - CursorPos = buf_byline(&Buffer, CursorPos, ScrollLines); - break; - default: - break; - } + if (mevnt->button >= 5) return; + /* update the number of clicks */ + uint32_t now = getmillis(); + uint32_t elapsed = now - Buttons[mevnt->button].time; + if (elapsed <= 250) + Buttons[mevnt->button].count++; + else + Buttons[mevnt->button].count = 1; + Buttons[mevnt->button].time = now; + /* execute the click action */ + uint32_t nclicks = Buttons[mevnt->button].count; + nclicks = (nclicks > 3 ? 1 : nclicks); + Actions[mevnt->button][nclicks-1](mevnt); }