vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: bf227f82582d6ca14931ba76b352dd6f0f4d9e18
Parent: 9bb775b76c7d37fa7ac446de2962846393119d27
Author: Randy Palamar
Date:   Sat, 16 Nov 2024 17:43:11 -0700

combine interaction type and variable

next_hot was removed because it is not needed when you process
input at the start of the frame. There are also advantages to
processing input later in the frame especially if you draw back to
front but then you are guaranteed to be one frame behind. So for
now we stick to start of the frame processing.

Diffstat:
Mdebug.c | 2+-
Mutil.h | 54+++++++++++++++++++++++++++++++++---------------------
Mvtgl.c | 72+++++++++++++++++++++++++++++++++++++++++-------------------------------
3 files changed, 75 insertions(+), 53 deletions(-)

diff --git a/debug.c b/debug.c @@ -239,7 +239,7 @@ draw_debug_bar_chart(Term *t, DebugState *ds, TerminalInput *input, RenderCtx *r hot_region_secs = cycs * cycs_to_secs; /* TODO: actually use the interaction system; for now we * just mask to prevent selection behind debug overlay */ - t->interaction.hot_interaction_state = IS_DEBUG; + t->interaction.hot.type = IS_DEBUG; } pos.x += r.size.w; } diff --git a/util.h b/util.h @@ -109,6 +109,26 @@ typedef struct { size len; u8 *data; } s8; typedef struct { iv2 start, end; } Range; #define INVALID_RANGE_END (iv2){.x = -1, .y = -1} +enum variable_type { + VT_NULL, + + VT_B32, + VT_U32, + VT_I32, + VT_F32, + VT_V4, + VT_S8, + VT_RANGE, + VT_VARIABLE, + + VT_GROUP, +}; + +typedef struct { + enum variable_type type; + void *value; +} Variable; + typedef struct { u8 *buf; u32 cap; @@ -416,39 +436,31 @@ typedef union { void *v; } Arg; -enum variable_type { - VT_NULL, - VT_B32, - VT_RANGE, - VT_GROUP, -}; - -typedef struct { - enum variable_type type; - void *value; -} Variable; - - #define INTERACTION_MULTI_CLICK_TIME 0.5f -enum interaction_states { +enum interaction_types { IS_NONE, IS_NOP, IS_SET, IS_DRAG, + IS_AUTO, + IS_DEBUG, IS_TERM, }; typedef struct { - Variable hot; - Variable next_hot; - Variable active; - u32 hot_interaction_state; - u32 click_count; - f32 multi_click_t; - enum interaction_states state; + Variable var; + enum interaction_types type; +} Interaction; + +typedef struct { + Interaction hot; + Interaction active; + + u32 click_count; + f32 multi_click_t; } InteractionState; enum selection_states { diff --git a/vtgl.c b/vtgl.c @@ -655,8 +655,11 @@ begin_selection(Term *t, u32 click_count, v2 mouse) cell.x--; } - if (sel->state == SS_WORDS) sel->anchor = sel->range = get_word_around_cell(t, cell); - else sel->anchor = (Range){.start = cell, .end = cell}; + switch (sel->state) { + case SS_WORDS: sel->anchor = sel->range = get_word_around_cell(t, cell); break; + case SS_CHAR: sel->anchor = (Range){.start = cell, .end = cell}; break; + case SS_NONE: break; + } t->gl.flags |= UPDATE_RENDER_BUFFER; } @@ -865,6 +868,14 @@ DEBUG_EXPORT VTGL_HANDLE_KEYS_FN(vtgl_handle_keys) } } +static b32 +should_start_interaction(TerminalInput *input) +{ + b32 result = input->mouse_scroll.y || input->mouse_scroll.x || + pressed_last_frame(input->keys + MOUSE_LEFT); + return result; +} + static void begin_interaction(InteractionState *is, TerminalInput *input) { @@ -872,31 +883,32 @@ begin_interaction(InteractionState *is, TerminalInput *input) if (is->multi_click_t < 0) is->multi_click_t = INTERACTION_MULTI_CLICK_TIME; - if (is->hot.value) { - if (is->hot_interaction_state) { - is->state = is->hot_interaction_state; - } else { - //switch (is->hot.type) { + if (is->hot.type != IS_NONE) { + if (is->hot.type == IS_AUTO) { + //switch (is->hot.var.type) { // /* TODO: start the interaction */ //} } - if (is->state != IS_NONE) - is->active = is->hot; + is->active = is->hot; - if (is->state == IS_TERM) - begin_selection(is->active.value, is->click_count, input->mouse); + switch (is->active.type) { + case IS_TERM: + if (pressed_last_frame(input->keys + MOUSE_LEFT)) + begin_selection(is->active.var.value, is->click_count, input->mouse); + break; + default: + break; + } } else { - is->state = IS_NOP; + is->active = (Interaction){.type = IS_NOP}; } } static void end_interaction(InteractionState *is) { - /* TODO: store the value */ - is->state = IS_NONE; - is->active = (Variable){0}; + is->active = (Interaction){0}; } static void @@ -904,25 +916,27 @@ handle_interactions(Term *t, TerminalInput *input, PlatformAPI *platform) { InteractionState *is = &t->interaction; - is->multi_click_t -= dt_for_frame; - ButtonState *mouse_left = input->keys + MOUSE_LEFT; b32 shift_down = input->modifiers & MOD_SHIFT; - if (is->state != IS_NONE) { - if (pressed_last_frame(mouse_left)) { + + is->multi_click_t -= dt_for_frame; + if (!mouse_left->ended_down && is->multi_click_t < 0) { + is->click_count = 0; + } + + if (is->hot.type != IS_NONE) { + if (should_start_interaction(input)) { end_interaction(is); begin_interaction(is, input); } - if (!mouse_left->ended_down && is->multi_click_t < 0) { - is->click_count = 0; - } - - switch (is->state) { + switch (is->active.type) { case IS_NONE: break; case IS_NOP: break; case IS_SET: end_interaction(is); break; - case IS_DRAG: /* TODO */ break; + case IS_AUTO: /* TODO */ break; + case IS_DRAG: /* TODO */ break; + case IS_DEBUG: /* TODO */ break; case IS_TERM: { update_selection(t, input); if (input->mouse_scroll.y) { @@ -949,11 +963,7 @@ handle_interactions(Term *t, TerminalInput *input, PlatformAPI *platform) if (pressed_last_frame(input->keys + MOUSE_MIDDLE)) paste(t, platform, (Arg){.i = CLIPBOARD_1}); } break; - case IS_DEBUG: /* TODO */ break; } - } else { - is->state = is->hot_interaction_state; - is->hot = is->next_hot; } } @@ -1166,8 +1176,8 @@ DEBUG_EXPORT VTGL_FRAME_STEP_FN(vtgl_frame_step) /* NOTE: default state which can be overwritten later in the frame */ /* TODO: if (!t->ui_active) */ - t->interaction.hot_interaction_state = IS_TERM; - t->interaction.next_hot = (Variable){.value = t}; + t->interaction.hot.type = IS_TERM; + t->interaction.hot.var = (Variable){.value = t}; END_NAMED_BLOCK(mouse_and_keyboard_input);