From 8c5c0be0408f4d3d601ec7548594d6ac392b61ea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 29 Mar 2024 11:17:01 -0700 Subject: [PATCH] ui: further improvements to double/triple dragging detection; df: use double/triple dragging to determine mouse-drag-range. dbl -> use token range, triple -> use line. pick appropriate side of mouse drag range on drag based on side of mark. --- src/base/base_core.c | 8 ++++++++ src/base/base_core.h | 1 + src/df/gfx/df_gfx.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- src/ui/ui_core.c | 10 ++++++++-- src/ui/ui_core.h | 1 + 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/base/base_core.c b/src/base/base_core.c index 24a6aaaa..2d40fe34 100644 --- a/src/base/base_core.c +++ b/src/base/base_core.c @@ -387,6 +387,14 @@ txt_rng_union(TxtRng a, TxtRng b) return result; } +internal B32 +txt_rng_contains(TxtRng r, TxtPt pt) +{ + B32 result = ((txt_pt_less_than(r.min, pt) || txt_pt_match(r.min, pt)) && + txt_pt_less_than(pt, r.max)); + return result; +} + //////////////////////////////// //~ rjf: Toolchain/Environment Enum Functions diff --git a/src/base/base_core.h b/src/base/base_core.h index c66772c1..87add9df 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -738,6 +738,7 @@ internal TxtPt txt_pt_max(TxtPt a, TxtPt b); internal TxtRng txt_rng(TxtPt min, TxtPt max); internal TxtRng txt_rng_intersect(TxtRng a, TxtRng b); internal TxtRng txt_rng_union(TxtRng a, TxtRng b); +internal B32 txt_rng_contains(TxtRng r, TxtPt pt); //////////////////////////////// //~ rjf: Toolchain/Environment Enum Functions diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 0d2da2b1..02a9ba04 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -9963,6 +9963,28 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ result.mouse_pt = mouse_pt; } + ////////////////////////////// + //- rjf: mouse point -> mouse token range, mouse line range + // + TxtRng mouse_token_rng = txt_rng(mouse_pt, mouse_pt); + TxtRng mouse_line_rng = txt_rng(mouse_pt, mouse_pt); + if(contains_1s64(params->line_num_range, mouse_pt.line)) + { + TXT_TokenArray *line_tokens = ¶ms->line_tokens[mouse_pt.line-params->line_num_range.min]; + Rng1U64 line_range = params->line_ranges[mouse_pt.line-params->line_num_range.min]; + U64 mouse_pt_off = (mouse_pt.column-1) + line_range.min; + for(U64 line_token_idx = 0; line_token_idx < line_tokens->count; line_token_idx += 1) + { + TXT_Token *line_token = &line_tokens->v[line_token_idx]; + if(contains_1u64(line_token->range, mouse_pt_off)) + { + mouse_token_rng = txt_rng(txt_pt(mouse_pt.line, 1+line_token->range.min-line_range.min), txt_pt(mouse_pt.line, 1+line_token->range.max-line_range.min)); + break; + } + } + mouse_line_rng = txt_rng(txt_pt(mouse_pt.line, 1), txt_pt(mouse_pt.line, 1+line_range.max)); + } + ////////////////////////////// //- rjf: interact with margin box & text box // @@ -9970,6 +9992,17 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ UI_Signal text_container_sig = ui_signal_from_box(text_container_box); DF_Entity *line_drag_entity = &df_g_nil_entity; { + //- rjf: determine mouse drag range + TxtRng mouse_drag_rng = txt_rng(mouse_pt, mouse_pt); + if(text_container_sig.f & UI_SignalFlag_LeftTripleDragging) + { + mouse_drag_rng = mouse_line_rng; + } + else if(text_container_sig.f & UI_SignalFlag_LeftDoubleDragging) + { + mouse_drag_rng = mouse_token_rng; + } + //- rjf: clicking/dragging over the text container if(!ctrlified && ui_dragging(text_container_sig)) { @@ -9987,9 +10020,17 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } if(ui_pressed(text_container_sig)) { - *mark = mouse_pt; + *cursor = mouse_drag_rng.max; + *mark = mouse_drag_rng.min; + } + if(txt_pt_less_than(mouse_pt, *mark)) + { + *cursor = mouse_drag_rng.min; + } + else + { + *cursor = mouse_drag_rng.max; } - *cursor = mouse_pt; *preferred_column = cursor->column; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 19a577f1..be62687e 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2464,8 +2464,11 @@ ui_signal_from_box(UI_Box *box) sizeof(ui_state->press_timestamp_history_us[evt_mouse_button_kind][0]) * ArrayCount(ui_state->press_timestamp_history_us[evt_mouse_button_kind])-1); MemoryCopy(&ui_state->press_key_history[evt_mouse_button_kind][1], &ui_state->press_key_history[evt_mouse_button_kind][0], sizeof(ui_state->press_key_history[evt_mouse_button_kind][0]) * ArrayCount(ui_state->press_key_history[evt_mouse_button_kind])-1); + MemoryCopy(&ui_state->press_pos_history[evt_mouse_button_kind][1], &ui_state->press_pos_history[evt_mouse_button_kind][0], + sizeof(ui_state->press_pos_history[evt_mouse_button_kind][0]) * ArrayCount(ui_state->press_pos_history[evt_mouse_button_kind])-1); ui_state->press_timestamp_history_us[evt_mouse_button_kind][0] = evt->timestamp_us; ui_state->press_key_history[evt_mouse_button_kind][0] = box->key; + ui_state->press_pos_history[evt_mouse_button_kind][0] = evt_mouse; taken = 1; } @@ -2652,7 +2655,8 @@ ui_signal_from_box(UI_Box *box) if(sig.f & (UI_SignalFlag_LeftDragging<press_key_history[k][0], box->key) && ui_key_match(ui_state->press_key_history[k][1], box->key) && - ui_state->press_timestamp_history_us[k][0] - ui_state->press_timestamp_history_us[k][1] <= 1000000*os_double_click_time()) + ui_state->press_timestamp_history_us[k][0] - ui_state->press_timestamp_history_us[k][1] <= 1000000*os_double_click_time() && + length_2f32(sub_2f32(ui_state->press_pos_history[k][0], ui_state->press_pos_history[k][1])) < 10.f) { sig.f |= (UI_SignalFlag_LeftDoubleDragging<press_key_history[k][1], box->key) && ui_key_match(ui_state->press_key_history[k][2], box->key) && ui_state->press_timestamp_history_us[k][0] - ui_state->press_timestamp_history_us[k][1] <= 1000000*os_double_click_time() && - ui_state->press_timestamp_history_us[k][1] - ui_state->press_timestamp_history_us[k][2] <= 1000000*os_double_click_time()) + ui_state->press_timestamp_history_us[k][1] - ui_state->press_timestamp_history_us[k][2] <= 1000000*os_double_click_time() && + length_2f32(sub_2f32(ui_state->press_pos_history[k][0], ui_state->press_pos_history[k][1])) < 10.f && + length_2f32(sub_2f32(ui_state->press_pos_history[k][1], ui_state->press_pos_history[k][2])) < 10.f) { sig.f |= (UI_SignalFlag_LeftTripleDragging<