commit 587eaf48e684bb58e21a9593a7361c97a8454cdb
parent 59b6d154e6cc299cb03b68f2ee34b73daee88ae3
Author: hhvn <dev@hhvn.uk>
Date: Sun, 20 Nov 2022 21:49:21 +0000
Add double click ability to items in a Treeview
Diffstat:
3 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/src/gui.c b/src/gui.c
@@ -1,9 +1,19 @@
#include <stdlib.h>
+#include <time.h>
+#include "maths.h"
#include "main.h"
+#define DOUBLE_CLICK (500.0 * MILLI / NANO)
+
static Clickable clickable[CLICKABLE_MAX];
static int clickablei = 0;
+static struct {
+ MouseButton button;
+ Vector pos;
+ struct timespec tv;
+} lastclick = {-1};
+
/* Click handlers */
static void gui_click_tabs(MouseButton button, Geom *geom, void *elem);
static void gui_click_checkbox(MouseButton button, Geom *geom, void *elem);
@@ -16,6 +26,7 @@ static void gui_click_treeview(MouseButton button, Geom *geom, void *elem);
static void gui_key_input(void *elem, int *fcount);
/* Other */
+static int gui_double_click(void);
static void gui_enter_input(Input *in);
static void (*click_handlers[GUI_ELEMS])(
@@ -83,9 +94,34 @@ gui_click_handle(void) {
if (button != -1 && !keepfocus)
ui_focus(0, NULL);
+ if (button != -1) {
+ lastclick.pos = mouse.vector;
+ lastclick.button = button;
+ clock_gettime(CLOCK_REALTIME, &lastclick.tv);
+ }
+
return ret;
}
+static int
+gui_double_click(void) {
+ struct timespec ctv;
+ struct timespec diff;
+
+ if (lastclick.button != MOUSE_BUTTON_LEFT ||
+ lastclick.pos.x != mouse.x ||
+ lastclick.pos.y != mouse.y)
+ return 0;
+
+ clock_gettime(CLOCK_REALTIME, &ctv);
+ timespec_diff(&ctv, &lastclick.tv, &diff);
+
+ if (diff.tv_sec == 0 && diff.tv_nsec < DOUBLE_CLICK)
+ return 1;
+
+ return 0;
+}
+
void
gui_tabs(int x, int y, int w, int h, Tabs *tabs) {
int fw, fn, ftabw;
@@ -427,7 +463,7 @@ gui_click_treeview(MouseButton button, Geom *geom, void *elem) {
Tree *p;
int i, pos;
- if (button == -1)
+ if (button != MOUSE_BUTTON_LEFT)
return;
pos = (mouse.y - geom->y - FONT_SIZE - (tv->print ? FONT_SIZE + PAD / 2 : 0) + tv->pane.off) / FONT_SIZE;
@@ -438,8 +474,12 @@ gui_click_treeview(MouseButton button, Geom *geom, void *elem) {
mouse.x < geom->x + PAD * (depth + 2)))
p->collapsed = !p->collapsed;
if (p->type & tv->selmask && (!(p->type & tv->colmask) ||
- mouse.x > geom->x + PAD * (depth + 2)))
- tv->sel = p;
+ mouse.x > geom->x + PAD * (depth + 2))) {
+ if (gui_double_click() && tv->dclick)
+ tv->dclick(tv);
+ else
+ tv->sel = p;
+ }
}
}
}
diff --git a/src/main.h b/src/main.h
@@ -225,3 +225,6 @@ void loading_close(Loader *hand);
float cosf_d(float x);
float sinf_d(float x);
float atan2f_d(float y, float x);
+
+/* time.c */
+void timespec_diff(struct timespec *t1, struct timespec *t2, struct timespec *diff);
diff --git a/src/time.c b/src/time.c
@@ -0,0 +1,23 @@
+#include <time.h>
+#include "maths.h"
+#include "main.h"
+
+void
+timespec_diff(struct timespec *t1, struct timespec *t2, struct timespec *diff) {
+ struct timespec *tmp;
+
+ if (t1->tv_sec < t2->tv_sec ||
+ (t1->tv_sec == t2->tv_sec && t1->tv_nsec < t2->tv_nsec)) {
+ tmp = t2;
+ t2 = t1;
+ t1 = tmp;
+ }
+
+ diff->tv_sec = t1->tv_sec - t2->tv_sec;
+ diff->tv_nsec = t1->tv_nsec - t2->tv_nsec;
+
+ if (diff->tv_nsec < 0) {
+ diff->tv_sec--;
+ diff->tv_nsec += NANO;
+ }
+}