Skip to content

Commit

Permalink
Reset the selection with single click
Browse files Browse the repository at this point in the history
In order to make it work I had to once again mess up with the 3d gesture
code, that it still a mess.
  • Loading branch information
guillaumechereau committed Jul 2, 2024
1 parent 5fcc3ea commit 31d1777
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 22 deletions.
69 changes: 54 additions & 15 deletions src/gesture3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,43 @@

#include "goxel.h"

static void update_drag(gesture3d_t *gest, bool pressed, bool btns_match)
enum {
GESTURE3D_STATE_FAILED = -1,
GESTURE3D_STATE_POSSIBLE = 0,
GESTURE3D_STATE_SNAPED = 1,
GESTURE3D_STATE_DOWN,
GESTURE3D_STATE_TRIGGERED,
};

static void update_drag(gesture3d_t *gest, bool pressed, bool btns_match,
int others_mask)
{
switch (gest->state) {
case GESTURE3D_STATE_POSSIBLE:
if (!btns_match) break;
if (others_mask & GESTURE3D_TYPE_DRAG) break;

if (gest->snaped && pressed) {
vec3_copy(gest->pos, gest->start_pos);
vec3_copy(gest->normal, gest->start_normal);
if (gest->flags & GESTURE3D_FLAG_DRAG_DELAY)
gest->state = GESTURE3D_STATE_DOWN;
else
gest->state = GESTURE3D_STATE_BEGIN;
}
break;

case GESTURE3D_STATE_DOWN:
// Require a bit of movement before starting.
if (!pressed) {
gest->state = GESTURE3D_STATE_POSSIBLE;
}
// XXX: should depend on 2d distance.
if (vec3_dist2(gest->pos, gest->start_pos) > 1) {
gest->state = GESTURE3D_STATE_BEGIN;
}
break;

case GESTURE3D_STATE_BEGIN:
case GESTURE3D_STATE_UPDATE:
gest->state = GESTURE3D_STATE_UPDATE;
Expand All @@ -44,13 +72,20 @@ static void update_click(gesture3d_t *gest, bool pressed, bool btns_match)
{
switch (gest->state) {
case GESTURE3D_STATE_POSSIBLE:
if (gest->snaped && !pressed) {
gest->state = GESTURE3D_STATE_RECOGNISED;
if (gest->snaped && !pressed && btns_match) {
gest->state = GESTURE3D_STATE_SNAPED;
}
break;
case GESTURE3D_STATE_RECOGNISED:
if (!btns_match) break;
if (gest->snaped && pressed) {
case GESTURE3D_STATE_SNAPED:
if (!gest->snaped || !btns_match) {
gest->state = GESTURE3D_STATE_POSSIBLE;
}
if (pressed) {
gest->state = GESTURE3D_STATE_DOWN;
}
break;
case GESTURE3D_STATE_DOWN:
if (!pressed) {
gest->state = GESTURE3D_STATE_TRIGGERED;
}
break;
Expand Down Expand Up @@ -87,12 +122,11 @@ static void update_hover(gesture3d_t *gest, bool pressed, bool btns_match)
}
break;
default:
assert(false);
break;
}
}

static int update_state(gesture3d_t *gest)
static int update_state(gesture3d_t *gest, int others_mask)
{
bool pressed = gest->flags & GESTURE3D_FLAG_PRESSED;
int r, ret = 0;
Expand All @@ -105,7 +139,7 @@ static int update_state(gesture3d_t *gest)
gest->state = GESTURE3D_STATE_POSSIBLE;

if (gest->type == GESTURE3D_TYPE_DRAG) {
update_drag(gest, pressed, btns_match);
update_drag(gest, pressed, btns_match, others_mask);
}

if (gest->type == GESTURE3D_TYPE_CLICK) {
Expand Down Expand Up @@ -139,7 +173,7 @@ static int update_state(gesture3d_t *gest)

int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[])
{
int i;
int i, others_mask = 0;
gesture3d_t *other, *match = NULL;

// Search if we already have this gesture in the list.
Expand All @@ -153,7 +187,7 @@ int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[])
// If no match add the gesture in the list.
if (i == *nb) {
match = &gestures[(*nb)++];
memset(match, 0, sizeof(*match));
*match = *gest;
}
assert(match);

Expand All @@ -165,14 +199,19 @@ int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[])
other->type == gest->type) {
continue;
}
if (other->type != GESTURE3D_TYPE_HOVER && other->state != 0) {
return false;
if ( other->type != GESTURE3D_TYPE_HOVER &&
other->state >= GESTURE3D_STATE_BEGIN) {
return 0;
}

if (other->state > GESTURE3D_STATE_POSSIBLE) {
others_mask |= other->type;
}
}

// Update the gesture data until it has started. That way we can
// modify the gesture inside its callback function.
if (match->state == 0) {
if (match->state < GESTURE3D_STATE_BEGIN) {
match->type = gest->type;
match->buttons = gest->buttons;
match->snap_mask = gest->snap_mask;
Expand All @@ -182,7 +221,7 @@ int gesture3d(const gesture3d_t *gest, int *nb, gesture3d_t gestures[])
}
match->user = gest->user;
match->alive = true;
return update_state(match);
return update_state(match, others_mask);
}

void gesture3d_remove_dead(int *nb, gesture3d_t gestures[])
Expand Down
9 changes: 4 additions & 5 deletions src/gesture3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,17 @@ enum {
};

enum {
GESTURE3D_STATE_POSSIBLE = 0,
GESTURE3D_STATE_RECOGNISED,
GESTURE3D_STATE_BEGIN,
GESTURE3D_STATE_BEGIN = 8,
GESTURE3D_STATE_UPDATE,
GESTURE3D_STATE_END,
GESTURE3D_STATE_TRIGGERED,
GESTURE3D_STATE_FAILED,
};

enum {
GESTURE3D_FLAG_PRESSED = 1 << 0,
GESTURE3D_FLAG_SHIFT = 1 << 1,
GESTURE3D_FLAG_CTRL = 1 << 2,
GESTURE3D_FLAG_OUT = 1 << 3, // Outside of sensing area.
GESTURE3D_FLAG_DRAG_DELAY = 1 << 4, // Don't drag until we move.
};

// #### 3d gestures
Expand All @@ -70,6 +67,8 @@ struct gesture3d
int flags;

// Updated by the 'gesture3d' function.
float start_pos[3];
float start_normal[3];
bool alive;
int state;
};
Expand Down
19 changes: 17 additions & 2 deletions src/tools/selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ static int on_hover(gesture3d_t *gest)
return 0;
}

static int on_click(gesture3d_t *gest)
{
action_exec2(ACTION_reset_selection);
return 0;
}

static int on_drag(gesture3d_t *gest)
{
tool_selection_t *tool = gest->user;
Expand All @@ -63,8 +69,9 @@ static int on_drag(gesture3d_t *gest)
goxel_set_help_text("Drag.");

get_rect(gest->pos, gest->normal, rect);
if (gest->state == GESTURE3D_STATE_BEGIN)
mat4_copy(rect, tool->start_rect);
if (gest->state == GESTURE3D_STATE_BEGIN) {
get_rect(gest->start_pos, gest->start_normal, tool->start_rect);
}

box_union(tool->start_rect, rect, goxel.selection);
// If the selection is flat, we grow it one voxel.
Expand Down Expand Up @@ -101,10 +108,18 @@ static int iter(tool_t *tool, const painter_t *painter,
.user = selection,
});

goxel_gesture3d(&(gesture3d_t) {
.type = GESTURE3D_TYPE_CLICK,
.snap_mask = snap_mask | SNAP_SELECTION_OUT,
.callback = on_click,
.user = selection,
});

goxel_gesture3d(&(gesture3d_t) {
.type = GESTURE3D_TYPE_DRAG,
.snap_mask = snap_mask & ~(SNAP_SELECTION_IN | SNAP_SELECTION_OUT),
.callback = on_drag,
.flags = GESTURE3D_FLAG_DRAG_DELAY,
.user = selection,
});

Expand Down

0 comments on commit 31d1777

Please sign in to comment.