From 00f41e79c7d9c18e40aca9f17b3f892109dbaf08 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 13 Apr 2023 09:09:44 -0700 Subject: [PATCH 01/12] WIP: VFONT: Text Selection Operator An operator to allow interactive text selection for 3D Text Objects. This is largely the code of Yash Dabhade (yashdabhade) for GSoC 2022 with corrections and simplifications. --- .../keyconfig/keymap_data/blender_default.py | 1 + .../keymap_data/industry_compatible_data.py | 1 + source/blender/blenkernel/BKE_vfont.h | 3 + source/blender/blenkernel/intern/vfont.c | 75 ++++++++++++- source/blender/editors/curve/curve_intern.h | 2 + source/blender/editors/curve/curve_ops.c | 2 + source/blender/editors/curve/editfont.c | 100 ++++++++++++++++++ 7 files changed, 182 insertions(+), 2 deletions(-) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index c47a17752f7..f5148db7cc0 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5611,6 +5611,7 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), + ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), diff --git a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index f141566e7cc..6210f4d2d79 100644 --- a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3803,6 +3803,7 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), + ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), diff --git a/source/blender/blenkernel/BKE_vfont.h b/source/blender/blenkernel/BKE_vfont.h index aea662d6548..908aa6a724c 100644 --- a/source/blender/blenkernel/BKE_vfont.h +++ b/source/blender/blenkernel/BKE_vfont.h @@ -72,6 +72,9 @@ bool BKE_vfont_to_curve_ex(struct Object *ob, bool *r_text_free, struct CharTrans **r_chartransdata); bool BKE_vfont_to_curve_nubase(struct Object *ob, int mode, struct ListBase *r_nubase); + +int BKE_vfont_cursor_to_caret_pos(struct Object *ob, float cursor_location[2]); + /** * \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one). */ diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index b6f9a23a3cd..a2281187077 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -778,7 +778,9 @@ static bool vfont_to_curve(Object *ob, const char32_t **r_text, int *r_text_len, bool *r_text_free, - struct CharTrans **r_chartransdata) + struct CharTrans **r_chartransdata, + float cursor_location[2], + int *r_caret_pos) { EditFont *ef = cu->editfont; EditFontSelBox *selboxes = NULL; @@ -911,6 +913,13 @@ static bool vfont_to_curve(Object *ob, } i = 0; + + int caret_pos = -1; + float caret_pos_min_dist = 0; + if (cursor_location && ef != NULL && ob != NULL) { + caret_pos_min_dist = len_squared_v2(cursor_location); + } + while (i <= slen) { /* Characters in the list */ info = &custrinfo[i]; @@ -1125,9 +1134,39 @@ static bool vfont_to_curve(Object *ob, } } ct++; + + BLI_assert((cursor_location == NULL) || (ob && ef)); + + if (cursor_location) { + float offset_loc[2] = {cursor_location[0] - xof, cursor_location[1] - yof}; + float di = len_squared_v2(offset_loc); + float di2 = len_squared_v2(cursor_location); + if (di2 <= caret_pos_min_dist && di2 < di) { + caret_pos_min_dist = di2; + caret_pos = -1; + } + else if (di < caret_pos_min_dist) { + caret_pos_min_dist = di; + caret_pos = i; + } + } + i++; } + if (cursor_location && r_caret_pos) { + if (caret_pos == -1) { + caret_pos++; + if (r_caret_pos) + *r_caret_pos = caret_pos; + } + else if (caret_pos >= 0 && caret_pos <= ef->len - 1) { + caret_pos++; + if (r_caret_pos) + *r_caret_pos = caret_pos; + } + } + current_line_length += xof + twidth - MARGIN_X_MIN; longest_line_length = MAX2(current_line_length, longest_line_length); @@ -1731,12 +1770,44 @@ bool BKE_vfont_to_curve_ex(Object *ob, do { data.ok &= vfont_to_curve( - ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata); + ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata, NULL, NULL); } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); return data.ok; } +int BKE_vfont_cursor_to_caret_pos(Object *ob, float cursor_location[2]) +{ + Curve *cu = (Curve *)ob->data; + ListBase *r_nubase = &cu->nurb; + int caret_pos = 0; + + /* TODO: iterating to calculate the scale can be avoided. */ + + VFontToCurveIter data = { + .iteraction = cu->totbox * FONT_TO_CURVE_SCALE_ITERATIONS, + .scale_to_fit = 1.0f, + .word_wrap = true, + .ok = true, + .status = VFONT_TO_CURVE_INIT, + }; + + do { + data.ok &= vfont_to_curve(ob, + cu, + FO_CURS, + &data, + r_nubase, + NULL, + NULL, + NULL, + NULL, + cursor_location, &caret_pos); + } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); + + return caret_pos; +} + #undef FONT_TO_CURVE_SCALE_ITERATIONS #undef FONT_TO_CURVE_SCALE_THRESHOLD diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 61a18dbd3e3..8f70027841e 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -84,6 +84,8 @@ void FONT_OT_text_cut(struct wmOperatorType *ot); void FONT_OT_text_paste(struct wmOperatorType *ot); void FONT_OT_text_paste_from_file(struct wmOperatorType *ot); +void FONT_OT_selection_set(struct wmOperatorType *ot); + void FONT_OT_move(struct wmOperatorType *ot); void FONT_OT_move_select(struct wmOperatorType *ot); void FONT_OT_delete(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 4e22008082d..4d7b47e2138 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -40,6 +40,8 @@ void ED_operatortypes_curve(void) WM_operatortype_append(FONT_OT_text_paste); WM_operatortype_append(FONT_OT_text_paste_from_file); + WM_operatortype_append(FONT_OT_selection_set); + WM_operatortype_append(FONT_OT_move); WM_operatortype_append(FONT_OT_move_select); WM_operatortype_append(FONT_OT_delete); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b1c8c9c4f22..1d653080c8f 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1796,6 +1796,106 @@ void FONT_OT_text_insert(wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Font Selection Operator + * \{ */ + +static void font_cursor_set_apply(bContext *C, const wmEvent *event) +{ + Object *obedit = CTX_data_active_object(C); + Curve *cu = obedit->data; + EditFont *ef = cu->editfont; + ARegion *region = CTX_wm_region(C); + int cur_loc_pos; + float rout[3]; + float mal_fl[2] = {(float)event->mval[0], (float)event->mval[1]}; + + const float *co = obedit->object_to_world[3]; + const float *no = obedit->object_to_world[2]; + float plane[4]; + plane_from_point_normal_v3(plane, co, no); + ED_view3d_win_to_3d_on_plane(region, plane, mal_fl, true, rout); + mul_m4_v3(obedit->world_to_object, rout); + float curs_loc[2] = {rout[0] / cu->fsize, rout[1] / cu->fsize}; + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Object *ob = DEG_get_evaluated_object(depsgraph, obedit); + cu = ob->data; + ef = cu->editfont; + BLI_assert(ef->len >= 0); + + cur_loc_pos = BKE_vfont_cursor_to_caret_pos(ob, curs_loc); + + cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0]; + + if (obedit->totcol > 0) { + obedit->actcol = cu->curinfo.mat_nr; + if (obedit->actcol < 1) { + obedit->actcol = 1; + } + } + + if (cur_loc_pos <= ef->len && cur_loc_pos >=0) { + if (!ef->selboxes && (ef->selstart == 0)) { + if (ef->pos == 0) { + ef->selstart = ef->selend = 1; + } + else { + ef->selstart = ef->selend = cur_loc_pos + 1; + } + } + ef->selend = cur_loc_pos; + ef->pos = cur_loc_pos; + } + + DEG_id_tag_update(obedit->data, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); +} + +static int font_selection_set_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *obedit = CTX_data_active_object(C); + Curve *cu = obedit->data; + EditFont *ef = cu->editfont; + + font_cursor_set_apply(C, event); + ef->selstart = 0; + ef->selend = 0; + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int font_selection_set_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +{ + switch (event->type) { + case LEFTMOUSE: // release + font_cursor_set_apply(C, event); + return OPERATOR_FINISHED; + case MIDDLEMOUSE: + case RIGHTMOUSE: + return OPERATOR_FINISHED; + case MOUSEMOVE: + font_cursor_set_apply(C, event); + break; + } + return OPERATOR_RUNNING_MODAL; +} + +void FONT_OT_selection_set(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Selection"; + ot->idname = "FONT_OT_selection_set"; + ot->description = "Set cursor selection"; + /* api callbacks */ + ot->invoke = font_selection_set_invoke; + ot->modal = font_selection_set_modal; + ot->poll = ED_operator_editfont; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Text-Box Add Operator * \{ */ -- 2.30.2 From 13a479248a6e5640c924d88db2c1f8bff40039a6 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 14 Apr 2023 12:58:05 -0700 Subject: [PATCH 02/12] Updated to incorporate all changes suggested by review --- source/blender/blenkernel/BKE_vfont.h | 2 +- source/blender/blenkernel/intern/vfont.c | 79 ++++++++++++------------ source/blender/editors/curve/editfont.c | 24 +++---- 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/source/blender/blenkernel/BKE_vfont.h b/source/blender/blenkernel/BKE_vfont.h index 908aa6a724c..b1a297a3413 100644 --- a/source/blender/blenkernel/BKE_vfont.h +++ b/source/blender/blenkernel/BKE_vfont.h @@ -73,7 +73,7 @@ bool BKE_vfont_to_curve_ex(struct Object *ob, struct CharTrans **r_chartransdata); bool BKE_vfont_to_curve_nubase(struct Object *ob, int mode, struct ListBase *r_nubase); -int BKE_vfont_cursor_to_caret_pos(struct Object *ob, float cursor_location[2]); +int BKE_vfont_cursor_to_string_offset(struct Object *ob, float cursor_location[2]); /** * \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one). diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index a2281187077..a2e5269c754 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -734,6 +734,14 @@ typedef struct VFontToCurveIter { int status; } VFontToCurveIter; +/* Used when translating a mouse cursor location to a position within the string. */ +typedef struct VFontCursor_Params { + /* Mouse cursor location as input. */ + float cursor_location[2]; + /* string character position as output. */ + int r_string_offset; +} VFontCursor_Params; + enum { VFONT_TO_CURVE_INIT = 0, VFONT_TO_CURVE_BISECT, @@ -779,8 +787,7 @@ static bool vfont_to_curve(Object *ob, int *r_text_len, bool *r_text_free, struct CharTrans **r_chartransdata, - float cursor_location[2], - int *r_caret_pos) + struct VFontCursor_Params *cursor_params) { EditFont *ef = cu->editfont; EditFontSelBox *selboxes = NULL; @@ -914,10 +921,12 @@ static bool vfont_to_curve(Object *ob, i = 0; - int caret_pos = -1; - float caret_pos_min_dist = 0; - if (cursor_location && ef != NULL && ob != NULL) { - caret_pos_min_dist = len_squared_v2(cursor_location); + float cursor_min_dist = 0; + float cursor_sq_dist = 0; + if (cursor_params) { + cursor_params->r_string_offset = -1; + cursor_sq_dist = len_squared_v2(cursor_params->cursor_location); + cursor_min_dist = cursor_sq_dist; } while (i <= slen) { @@ -1135,35 +1144,27 @@ static bool vfont_to_curve(Object *ob, } ct++; - BLI_assert((cursor_location == NULL) || (ob && ef)); - - if (cursor_location) { - float offset_loc[2] = {cursor_location[0] - xof, cursor_location[1] - yof}; - float di = len_squared_v2(offset_loc); - float di2 = len_squared_v2(cursor_location); - if (di2 <= caret_pos_min_dist && di2 < di) { - caret_pos_min_dist = di2; - caret_pos = -1; + if (cursor_params) { + float offset_loc[2] = {cursor_params->cursor_location[0] - xof, + cursor_params->cursor_location[1] - yof}; + float cursor_sq_offset = len_squared_v2(offset_loc); + if (cursor_sq_dist <= cursor_min_dist && cursor_sq_dist < cursor_sq_offset) { + cursor_min_dist = cursor_sq_dist; + cursor_params->r_string_offset = -1; } - else if (di < caret_pos_min_dist) { - caret_pos_min_dist = di; - caret_pos = i; + else if (cursor_sq_offset < cursor_min_dist) { + cursor_min_dist = cursor_sq_offset; + cursor_params->r_string_offset = i; } } i++; } - if (cursor_location && r_caret_pos) { - if (caret_pos == -1) { - caret_pos++; - if (r_caret_pos) - *r_caret_pos = caret_pos; - } - else if (caret_pos >= 0 && caret_pos <= ef->len - 1) { - caret_pos++; - if (r_caret_pos) - *r_caret_pos = caret_pos; + if (cursor_params) { + if (cursor_params->r_string_offset == -1 || + (cursor_params->r_string_offset >= 0 && cursor_params->r_string_offset <= ef->len - 1)) { + cursor_params->r_string_offset++; } } @@ -1776,11 +1777,10 @@ bool BKE_vfont_to_curve_ex(Object *ob, return data.ok; } -int BKE_vfont_cursor_to_caret_pos(Object *ob, float cursor_location[2]) +int BKE_vfont_cursor_to_string_offset(Object *ob, float cursor_location[2]) { Curve *cu = (Curve *)ob->data; ListBase *r_nubase = &cu->nurb; - int caret_pos = 0; /* TODO: iterating to calculate the scale can be avoided. */ @@ -1792,20 +1792,17 @@ int BKE_vfont_cursor_to_caret_pos(Object *ob, float cursor_location[2]) .status = VFONT_TO_CURVE_INIT, }; + VFontCursor_Params cursor_params = { + .cursor_location = {cursor_location[0], cursor_location[1]}, + .r_string_offset = 0, + }; + do { - data.ok &= vfont_to_curve(ob, - cu, - FO_CURS, - &data, - r_nubase, - NULL, - NULL, - NULL, - NULL, - cursor_location, &caret_pos); + data.ok &= vfont_to_curve( + ob, cu, FO_CURS, &data, r_nubase, NULL, NULL, NULL, NULL, &cursor_params); } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); - return caret_pos; + return cursor_params.r_string_offset; } #undef FONT_TO_CURVE_SCALE_ITERATIONS diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 1d653080c8f..0f452107e87 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1824,7 +1824,11 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) ef = cu->editfont; BLI_assert(ef->len >= 0); - cur_loc_pos = BKE_vfont_cursor_to_caret_pos(ob, curs_loc); + cur_loc_pos = BKE_vfont_cursor_to_string_offset(ob, curs_loc); + + if (cur_loc_pos > ef->len || cur_loc_pos < 0 || ef->selend == cur_loc_pos) { + return; + } cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0]; @@ -1835,18 +1839,16 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) } } - if (cur_loc_pos <= ef->len && cur_loc_pos >=0) { - if (!ef->selboxes && (ef->selstart == 0)) { - if (ef->pos == 0) { - ef->selstart = ef->selend = 1; - } - else { - ef->selstart = ef->selend = cur_loc_pos + 1; - } + if (!ef->selboxes && (ef->selstart == 0)) { + if (ef->pos == 0) { + ef->selstart = ef->selend = 1; + } + else { + ef->selstart = ef->selend = cur_loc_pos + 1; } - ef->selend = cur_loc_pos; - ef->pos = cur_loc_pos; } + ef->selend = cur_loc_pos; + ef->pos = cur_loc_pos; DEG_id_tag_update(obedit->data, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); -- 2.30.2 From 19454f61bb2ac2da02ab99b4a909b56d2ab66db5 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 14 Apr 2023 14:21:42 -0700 Subject: [PATCH 03/12] Adding the word selection operator back in. --- .../keyconfig/keymap_data/blender_default.py | 1 + .../keymap_data/industry_compatible_data.py | 1 + source/blender/editors/curve/curve_intern.h | 1 + source/blender/editors/curve/curve_ops.c | 1 + source/blender/editors/curve/editfont.c | 27 +++++++++++++++++++ 5 files changed, 31 insertions(+) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index f5148db7cc0..fba2ba387c5 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5612,6 +5612,7 @@ def km_font(params): ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), diff --git a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 6210f4d2d79..721695ff3bf 100644 --- a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3804,6 +3804,7 @@ def km_font(params): ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 8f70027841e..7a20634a2be 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -85,6 +85,7 @@ void FONT_OT_text_paste(struct wmOperatorType *ot); void FONT_OT_text_paste_from_file(struct wmOperatorType *ot); void FONT_OT_selection_set(struct wmOperatorType *ot); +void FONT_OT_select_word(struct wmOperatorType *ot); void FONT_OT_move(struct wmOperatorType *ot); void FONT_OT_move_select(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 4d7b47e2138..a1eecaece47 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -41,6 +41,7 @@ void ED_operatortypes_curve(void) WM_operatortype_append(FONT_OT_text_paste_from_file); WM_operatortype_append(FONT_OT_selection_set); + WM_operatortype_append(FONT_OT_select_word); WM_operatortype_append(FONT_OT_move); WM_operatortype_append(FONT_OT_move_select); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 0f452107e87..cee629e1694 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1890,6 +1890,7 @@ void FONT_OT_selection_set(struct wmOperatorType *ot) ot->name = "Set Selection"; ot->idname = "FONT_OT_selection_set"; ot->description = "Set cursor selection"; + /* api callbacks */ ot->invoke = font_selection_set_invoke; ot->modal = font_selection_set_modal; @@ -1898,6 +1899,32 @@ void FONT_OT_selection_set(struct wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Select Word Operator +* \{ */ + +static int font_select_word_exec(bContext *C, wmOperator *UNUSED(op)) +{ + move_cursor(C, NEXT_CHAR, false); + move_cursor(C, PREV_WORD, false); + move_cursor(C, NEXT_WORD, true); + return OPERATOR_FINISHED; +} + +void FONT_OT_select_word(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Word"; + ot->idname = "FONT_OT_select_word"; + ot->description = "Select word under cursor"; + + /* api callbacks */ + ot->exec = font_select_word_exec; + ot->poll = ED_operator_editfont; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Text-Box Add Operator * \{ */ -- 2.30.2 From 2deda6724d25b10b0dd3c0561f82aa99e212d142 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Tue, 18 Apr 2023 09:32:57 -0700 Subject: [PATCH 04/12] Many, not all, changes suggested by review. --- source/blender/blenkernel/intern/vfont.c | 31 +++++++++++++----- source/blender/editors/curve/editfont.c | 40 +++++++++++++----------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index a2e5269c754..3d9aa967aca 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -734,11 +734,19 @@ typedef struct VFontToCurveIter { int status; } VFontToCurveIter; + +/* -------------------------------------------------------------------- */ +/** \name VFont Mouse Cursor to Text Offset + * + * This is an optional argument to `vfont_to_curve` for getting the text + * offset into the string at a mouse cursor location. Used for getting + * text cursor (caret) position or selection range. + * \{ */ /* Used when translating a mouse cursor location to a position within the string. */ typedef struct VFontCursor_Params { - /* Mouse cursor location as input. */ + /* Mouse cursor location in Object coordinate space as input. */ float cursor_location[2]; - /* string character position as output. */ + /* Character position within EditFont::textbuf as output. */ int r_string_offset; } VFontCursor_Params; @@ -782,12 +790,12 @@ static bool vfont_to_curve(Object *ob, Curve *cu, int mode, VFontToCurveIter *iter_data, + struct VFontCursor_Params *cursor_params, ListBase *r_nubase, const char32_t **r_text, int *r_text_len, bool *r_text_free, - struct CharTrans **r_chartransdata, - struct VFontCursor_Params *cursor_params) + struct CharTrans **r_chartransdata) { EditFont *ef = cu->editfont; EditFontSelBox *selboxes = NULL; @@ -1770,8 +1778,17 @@ bool BKE_vfont_to_curve_ex(Object *ob, }; do { - data.ok &= vfont_to_curve( - ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata, NULL, NULL); + data.ok &= vfont_to_curve(ob, + cu, + mode, + &data, + NULL, + r_nubase, + r_text, + r_text_len, + r_text_free, + r_chartransdata, + NULL); } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); return data.ok; @@ -1799,7 +1816,7 @@ int BKE_vfont_cursor_to_string_offset(Object *ob, float cursor_location[2]) do { data.ok &= vfont_to_curve( - ob, cu, FO_CURS, &data, r_nubase, NULL, NULL, NULL, NULL, &cursor_params); + ob, cu, FO_CURS, &data, &cursor_params, r_nubase, NULL, NULL, NULL, NULL); } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); return cursor_params.r_string_offset; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index cee629e1694..8e04069eeef 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1805,18 +1805,19 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) Object *obedit = CTX_data_active_object(C); Curve *cu = obedit->data; EditFont *ef = cu->editfont; - ARegion *region = CTX_wm_region(C); - int cur_loc_pos; - float rout[3]; - float mal_fl[2] = {(float)event->mval[0], (float)event->mval[1]}; - const float *co = obedit->object_to_world[3]; - const float *no = obedit->object_to_world[2]; + /* Calculate a plane from the text object's orientation. */ float plane[4]; - plane_from_point_normal_v3(plane, co, no); - ED_view3d_win_to_3d_on_plane(region, plane, mal_fl, true, rout); - mul_m4_v3(obedit->world_to_object, rout); - float curs_loc[2] = {rout[0] / cu->fsize, rout[1] / cu->fsize}; + plane_from_point_normal_v3(plane, obedit->object_to_world[3], obedit->object_to_world[2]); + + /* Convert Mouse location in region to 3D location in world space. */ + float mal_fl[2] = {(float)event->mval[0], (float)event->mval[1]}; + float mouse_loc[3]; + ED_view3d_win_to_3d_on_plane(CTX_wm_region(C), plane, mal_fl, true, mouse_loc); + + /* Convert to object space and scale by font size. */ + mul_m4_v3(obedit->world_to_object, mouse_loc); + float curs_loc[2] = {mouse_loc[0] / cu->fsize, mouse_loc[1] / cu->fsize}; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Object *ob = DEG_get_evaluated_object(depsgraph, obedit); @@ -1824,9 +1825,9 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) ef = cu->editfont; BLI_assert(ef->len >= 0); - cur_loc_pos = BKE_vfont_cursor_to_string_offset(ob, curs_loc); + const int string_offset = BKE_vfont_cursor_to_string_offset(ob, curs_loc); - if (cur_loc_pos > ef->len || cur_loc_pos < 0 || ef->selend == cur_loc_pos) { + if (string_offset > ef->len || string_offset < 0 || ef->selend == string_offset) { return; } @@ -1844,11 +1845,11 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) ef->selstart = ef->selend = 1; } else { - ef->selstart = ef->selend = cur_loc_pos + 1; + ef->selstart = ef->selend = string_offset + 1; } } - ef->selend = cur_loc_pos; - ef->pos = cur_loc_pos; + ef->selend = string_offset; + ef->pos = string_offset; DEG_id_tag_update(obedit->data, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); @@ -1871,9 +1872,12 @@ static int font_selection_set_invoke(bContext *C, wmOperator *op, const wmEvent static int font_selection_set_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { switch (event->type) { - case LEFTMOUSE: // release - font_cursor_set_apply(C, event); - return OPERATOR_FINISHED; + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + font_cursor_set_apply(C, event); + return OPERATOR_FINISHED; + } + break; case MIDDLEMOUSE: case RIGHTMOUSE: return OPERATOR_FINISHED; -- 2.30.2 From e8280fb455b0be99491f25fb4d85ef42da3efbf7 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Wed, 19 Apr 2023 14:56:28 -0700 Subject: [PATCH 05/12] The rest of the review suggestions --- source/blender/blenkernel/intern/vfont.c | 20 ++++++++++---------- source/blender/editors/curve/editfont.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index 3d9aa967aca..b90881271cc 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -929,12 +929,11 @@ static bool vfont_to_curve(Object *ob, i = 0; - float cursor_min_dist = 0; - float cursor_sq_dist = 0; + float cursor_sq_dist_best = FLT_MAX; + float cursor_sq_dist_test = 0; if (cursor_params) { cursor_params->r_string_offset = -1; - cursor_sq_dist = len_squared_v2(cursor_params->cursor_location); - cursor_min_dist = cursor_sq_dist; + cursor_sq_dist_test = len_squared_v2(cursor_params->cursor_location); } while (i <= slen) { @@ -1156,14 +1155,15 @@ static bool vfont_to_curve(Object *ob, float offset_loc[2] = {cursor_params->cursor_location[0] - xof, cursor_params->cursor_location[1] - yof}; float cursor_sq_offset = len_squared_v2(offset_loc); - if (cursor_sq_dist <= cursor_min_dist && cursor_sq_dist < cursor_sq_offset) { - cursor_min_dist = cursor_sq_dist; - cursor_params->r_string_offset = -1; - } - else if (cursor_sq_offset < cursor_min_dist) { - cursor_min_dist = cursor_sq_offset; + if (cursor_sq_offset < cursor_sq_dist_best) { + /* Closest character so far. */ + cursor_sq_dist_best = cursor_sq_offset; cursor_params->r_string_offset = i; } + else if (cursor_sq_dist_test < cursor_sq_dist_best) { + /* Left of text, including left-side of first character. */ + cursor_params->r_string_offset = -1; + } } i++; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 8e04069eeef..2c4fe1203f2 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1827,7 +1827,7 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) const int string_offset = BKE_vfont_cursor_to_string_offset(ob, curs_loc); - if (string_offset > ef->len || string_offset < 0 || ef->selend == string_offset) { + if (string_offset > ef->len || string_offset < 0) { return; } -- 2.30.2 From 8a8724c139c2620c5f329f6f66b170f7f8ee00bd Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Wed, 19 Apr 2023 19:40:04 -0700 Subject: [PATCH 06/12] Changes suggested by review --- source/blender/blenkernel/BKE_vfont.h | 2 +- source/blender/blenkernel/intern/vfont.c | 47 +++++++++--------------- source/blender/editors/curve/editfont.c | 43 +++++++++++++--------- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/source/blender/blenkernel/BKE_vfont.h b/source/blender/blenkernel/BKE_vfont.h index b1a297a3413..fd4c23f649e 100644 --- a/source/blender/blenkernel/BKE_vfont.h +++ b/source/blender/blenkernel/BKE_vfont.h @@ -73,7 +73,7 @@ bool BKE_vfont_to_curve_ex(struct Object *ob, struct CharTrans **r_chartransdata); bool BKE_vfont_to_curve_nubase(struct Object *ob, int mode, struct ListBase *r_nubase); -int BKE_vfont_cursor_to_string_offset(struct Object *ob, float cursor_location[2]); +int BKE_vfont_cursor_to_text_index(struct Object *ob, float cursor_location[2]); /** * \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one). diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index b90881271cc..6f893c40268 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -929,13 +929,6 @@ static bool vfont_to_curve(Object *ob, i = 0; - float cursor_sq_dist_best = FLT_MAX; - float cursor_sq_dist_test = 0; - if (cursor_params) { - cursor_params->r_string_offset = -1; - cursor_sq_dist_test = len_squared_v2(cursor_params->cursor_location); - } - while (i <= slen) { /* Characters in the list */ info = &custrinfo[i]; @@ -1141,9 +1134,9 @@ static bool vfont_to_curve(Object *ob, } /* Set the width of the character. */ - twidth = char_width(cu, che, info); + twidth = (char_width(cu, che, info) * wsfac * (1.0f + (info->kern / 40.0f))) + xtrax; - xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f))) + xtrax; + xof += twidth; if (sb) { sb->w = (xof * font_size) - sb->w; @@ -1152,30 +1145,26 @@ static bool vfont_to_curve(Object *ob, ct++; if (cursor_params) { - float offset_loc[2] = {cursor_params->cursor_location[0] - xof, - cursor_params->cursor_location[1] - yof}; - float cursor_sq_offset = len_squared_v2(offset_loc); - if (cursor_sq_offset < cursor_sq_dist_best) { - /* Closest character so far. */ - cursor_sq_dist_best = cursor_sq_offset; - cursor_params->r_string_offset = i; - } - else if (cursor_sq_dist_test < cursor_sq_dist_best) { - /* Left of text, including left-side of first character. */ - cursor_params->r_string_offset = -1; + float midw = (twidth / 2.0f); + if (cursor_params->cursor_location[1] >= yof - (0.25f * linedist) && + cursor_params->cursor_location[1] <= (yof + (0.75f * linedist))) { + /* On this row. */ + if (cursor_params->cursor_location[0] >= (xof - twidth) && + cursor_params->cursor_location[0] <= (xof - midw)) { + /* Left half of preceding character. */ + cursor_params->r_string_offset = i; + } + else if (cursor_params->cursor_location[0] >= (xof - midw) && + cursor_params->cursor_location[0] <= (xof)) { + /* Right half of preceding character. */ + cursor_params->r_string_offset = i + 1; + } } } i++; } - if (cursor_params) { - if (cursor_params->r_string_offset == -1 || - (cursor_params->r_string_offset >= 0 && cursor_params->r_string_offset <= ef->len - 1)) { - cursor_params->r_string_offset++; - } - } - current_line_length += xof + twidth - MARGIN_X_MIN; longest_line_length = MAX2(current_line_length, longest_line_length); @@ -1794,7 +1783,7 @@ bool BKE_vfont_to_curve_ex(Object *ob, return data.ok; } -int BKE_vfont_cursor_to_string_offset(Object *ob, float cursor_location[2]) +int BKE_vfont_cursor_to_text_index(Object *ob, float cursor_location[2]) { Curve *cu = (Curve *)ob->data; ListBase *r_nubase = &cu->nurb; @@ -1811,7 +1800,7 @@ int BKE_vfont_cursor_to_string_offset(Object *ob, float cursor_location[2]) VFontCursor_Params cursor_params = { .cursor_location = {cursor_location[0], cursor_location[1]}, - .r_string_offset = 0, + .r_string_offset = -1, }; do { diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 2c4fe1203f2..c5cf9b8497b 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1796,13 +1796,11 @@ void FONT_OT_text_insert(wmOperatorType *ot) /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Font Selection Operator - * \{ */ - -static void font_cursor_set_apply(bContext *C, const wmEvent *event) +static void font_cursor_text_index_from_event(bContext *C, + Object *obedit, + const wmEvent *event, + float r_curs_loc[2]) { - Object *obedit = CTX_data_active_object(C); Curve *cu = obedit->data; EditFont *ef = cu->editfont; @@ -1817,15 +1815,26 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) /* Convert to object space and scale by font size. */ mul_m4_v3(obedit->world_to_object, mouse_loc); - float curs_loc[2] = {mouse_loc[0] / cu->fsize, mouse_loc[1] / cu->fsize}; + r_curs_loc[0] = mouse_loc[0] / cu->fsize; + r_curs_loc[1] = mouse_loc[1] / cu->fsize; +} + +/* -------------------------------------------------------------------- */ +/** \name Font Selection Operator + * \{ */ + +static void font_cursor_set_apply(bContext *C, const wmEvent *event) +{ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Object *ob = DEG_get_evaluated_object(depsgraph, obedit); - cu = ob->data; - ef = cu->editfont; + Object *ob = DEG_get_evaluated_object(depsgraph, CTX_data_active_object(C)); + Curve *cu = ob->data; + EditFont *ef = cu->editfont; BLI_assert(ef->len >= 0); - const int string_offset = BKE_vfont_cursor_to_string_offset(ob, curs_loc); + float curs_loc[2]; + font_cursor_text_index_from_event(C, ob, event, curs_loc); + const int string_offset = BKE_vfont_cursor_to_text_index(ob, curs_loc); if (string_offset > ef->len || string_offset < 0) { return; @@ -1833,10 +1842,10 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0]; - if (obedit->totcol > 0) { - obedit->actcol = cu->curinfo.mat_nr; - if (obedit->actcol < 1) { - obedit->actcol = 1; + if (ob->totcol > 0) { + ob->actcol = cu->curinfo.mat_nr; + if (ob->actcol < 1) { + ob->actcol = 1; } } @@ -1851,8 +1860,8 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) ef->selend = string_offset; ef->pos = string_offset; - DEG_id_tag_update(obedit->data, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DEG_id_tag_update(ob->data, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); } static int font_selection_set_invoke(bContext *C, wmOperator *op, const wmEvent *event) -- 2.30.2 From 10c27713d7e8c3c0e4be2f265b9ee6393f95e668 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 20 Apr 2023 09:35:28 -0700 Subject: [PATCH 07/12] Finding cursor location after transformations. Other review changes. --- source/blender/blenkernel/intern/vfont.c | 55 +++++++++++++++--------- source/blender/editors/curve/editfont.c | 21 ++++----- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index 6f893c40268..abda872ac93 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -734,6 +734,7 @@ typedef struct VFontToCurveIter { int status; } VFontToCurveIter; +/** \} */ /* -------------------------------------------------------------------- */ /** \name VFont Mouse Cursor to Text Offset @@ -750,6 +751,8 @@ typedef struct VFontCursor_Params { int r_string_offset; } VFontCursor_Params; +/** \} */ + enum { VFONT_TO_CURVE_INIT = 0, VFONT_TO_CURVE_BISECT, @@ -928,7 +931,6 @@ static bool vfont_to_curve(Object *ob, } i = 0; - while (i <= slen) { /* Characters in the list */ info = &custrinfo[i]; @@ -1134,9 +1136,9 @@ static bool vfont_to_curve(Object *ob, } /* Set the width of the character. */ - twidth = (char_width(cu, che, info) * wsfac * (1.0f + (info->kern / 40.0f))) + xtrax; + twidth = char_width(cu, che, info); - xof += twidth; + xof += (twidth * wsfac * (1.0f + (info->kern / 40.0f))) + xtrax; if (sb) { sb->w = (xof * font_size) - sb->w; @@ -1144,24 +1146,6 @@ static bool vfont_to_curve(Object *ob, } ct++; - if (cursor_params) { - float midw = (twidth / 2.0f); - if (cursor_params->cursor_location[1] >= yof - (0.25f * linedist) && - cursor_params->cursor_location[1] <= (yof + (0.75f * linedist))) { - /* On this row. */ - if (cursor_params->cursor_location[0] >= (xof - twidth) && - cursor_params->cursor_location[0] <= (xof - midw)) { - /* Left half of preceding character. */ - cursor_params->r_string_offset = i; - } - else if (cursor_params->cursor_location[0] >= (xof - midw) && - cursor_params->cursor_location[0] <= (xof)) { - /* Right half of preceding character. */ - cursor_params->r_string_offset = i + 1; - } - } - } - i++; } @@ -1470,6 +1454,35 @@ static bool vfont_to_curve(Object *ob, } } + if (cursor_params) { + cursor_params->r_string_offset = -1; + for (i = 0; i <= slen; i++, ct++) { + info = &custrinfo[i]; + ascii = mem[i]; + if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) { + ascii = towupper(ascii); + } + ct = &chartransdata[i]; + che = find_vfont_char(vfd, ascii); + float charwidth = char_width(cu, che, info); + float charhalf = (charwidth / 2.0f); + if (cursor_params->cursor_location[1] >= ct->yof - (0.25f * linedist) && + cursor_params->cursor_location[1] <= (ct->yof + (0.75f * linedist))) { + /* On this row. */ + if (cursor_params->cursor_location[0] >= (ct->xof) && + cursor_params->cursor_location[0] <= (ct->xof + charhalf)) { + /* Left half of character. */ + cursor_params->r_string_offset = i; + } + else if (cursor_params->cursor_location[0] >= (ct->xof + charhalf) && + cursor_params->cursor_location[0] <= (ct->xof + charwidth)) { + /* Right half of character. */ + cursor_params->r_string_offset = i + 1; + } + } + } + } + if (ELEM(mode, FO_CURSUP, FO_CURSDOWN, FO_PAGEUP, FO_PAGEDOWN) && iter_data->status == VFONT_TO_CURVE_INIT) { ct = &chartransdata[ef->pos]; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index c5cf9b8497b..aeb57e36a65 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1796,10 +1796,11 @@ void FONT_OT_text_insert(wmOperatorType *ot) /** \} */ -static void font_cursor_text_index_from_event(bContext *C, - Object *obedit, - const wmEvent *event, - float r_curs_loc[2]) +/* -------------------------------------------------------------------- */ +/** \name Font Selection Operator + * \{ */ + +static int font_cursor_text_index_from_event(bContext *C, Object *obedit, const wmEvent *event) { Curve *cu = obedit->data; EditFont *ef = cu->editfont; @@ -1816,14 +1817,10 @@ static void font_cursor_text_index_from_event(bContext *C, /* Convert to object space and scale by font size. */ mul_m4_v3(obedit->world_to_object, mouse_loc); - r_curs_loc[0] = mouse_loc[0] / cu->fsize; - r_curs_loc[1] = mouse_loc[1] / cu->fsize; + float curs_loc[2] = {mouse_loc[0] / cu->fsize, mouse_loc[1] / cu->fsize}; + return BKE_vfont_cursor_to_text_index(obedit, curs_loc); } -/* -------------------------------------------------------------------- */ -/** \name Font Selection Operator - * \{ */ - static void font_cursor_set_apply(bContext *C, const wmEvent *event) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -1832,9 +1829,7 @@ static void font_cursor_set_apply(bContext *C, const wmEvent *event) EditFont *ef = cu->editfont; BLI_assert(ef->len >= 0); - float curs_loc[2]; - font_cursor_text_index_from_event(C, ob, event, curs_loc); - const int string_offset = BKE_vfont_cursor_to_text_index(ob, curs_loc); + const int string_offset = font_cursor_text_index_from_event(C, ob, event); if (string_offset > ef->len || string_offset < 0) { return; -- 2.30.2 From 98ced9cd79ee366d3ad03cc7f10a54dbba158cab Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 20 Apr 2023 09:38:12 -0700 Subject: [PATCH 08/12] Unintentional white space change --- source/blender/blenkernel/intern/vfont.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index abda872ac93..605c9494a8a 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -1145,7 +1145,6 @@ static bool vfont_to_curve(Object *ob, } } ct++; - i++; } -- 2.30.2 From 587a61d16efbeeb5423c1cb222b8e0eeafbec66a Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 20 Apr 2023 18:22:11 -0700 Subject: [PATCH 09/12] function had one extra argument. Yikes --- source/blender/blenkernel/intern/vfont.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/vfont.c b/source/blender/blenkernel/intern/vfont.c index 605c9494a8a..38a2f38df70 100644 --- a/source/blender/blenkernel/intern/vfont.c +++ b/source/blender/blenkernel/intern/vfont.c @@ -1788,8 +1788,7 @@ bool BKE_vfont_to_curve_ex(Object *ob, r_text, r_text_len, r_text_free, - r_chartransdata, - NULL); + r_chartransdata); } while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT)); return data.ok; -- 2.30.2 From f9808406664eb2a6acff4c04d54a3a4376defd27 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 20 Apr 2023 20:53:05 -0700 Subject: [PATCH 10/12] Make a tool for text selection. --- .../keyconfig/keymap_data/blender_default.py | 12 +++++++++++- .../keymap_data/industry_compatible_data.py | 1 - scripts/startup/bl_ui/space_toolsystem_toolbar.py | 15 +++++++++++++++ .../blender/windowmanager/intern/wm_toolsystem.c | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index fba2ba387c5..307b3687cbb 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5611,7 +5611,6 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), @@ -6782,6 +6781,16 @@ def km_3d_view_tool_cursor(params): ) +def km_3d_view_tool_text_select(params): + return ( + "3D View Tool: Text Select", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ]}, + ) + + def km_3d_view_tool_select(params, *, fallback): if params.use_tweak_select_passthrough: operator_props = (("vert_without_handles", True),) @@ -8195,6 +8204,7 @@ def generate_keymaps(params=None): *(km_node_editor_tool_select_circle(params, fallback=fallback) for fallback in (False, True)), km_node_editor_tool_links_cut(params), km_3d_view_tool_cursor(params), + km_3d_view_tool_text_select(params), *(km_3d_view_tool_select(params, fallback=fallback) for fallback in (False, True)), *(km_3d_view_tool_select_box(params, fallback=fallback) for fallback in (False, True)), *(km_3d_view_tool_select_circle(params, fallback=fallback) for fallback in (False, True)), diff --git a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 721695ff3bf..fb7d0f23126 100644 --- a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3803,7 +3803,6 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 2022f867059..981e7a73c2d 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1259,6 +1259,20 @@ class _defs_edit_curve: ) +class _defs_edit_text: + + @ToolDef.from_fn + def select_text(): + return dict( + idname="builtin.select_text", + label="Select Text", + cursor='CROSSHAIR', + icon="ops.generic.select_box", + widget=None, + keymap=("3D View Tool: Text Select"), + ) + + class _defs_pose: @ToolDef.from_fn @@ -3028,6 +3042,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_transform.shear, ], 'EDIT_TEXT': [ + _defs_edit_text.select_text, _defs_view3d_generic.cursor, None, *_tools_annotate, diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index 1a6aa974a7b..a8a82251f26 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -729,7 +729,7 @@ static const char *toolsystem_default_tool(const bToolKey *tkey) case CTX_MODE_PARTICLE: return "builtin_brush.Comb"; case CTX_MODE_EDIT_TEXT: - return "builtin.cursor"; + return "builtin.select_text"; } break; case SPACE_IMAGE: -- 2.30.2 From 6e60e1507f468afa30fbe9da9532b9369d96de96 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 21 Apr 2023 09:35:56 -0700 Subject: [PATCH 11/12] Changes suggested by review --- scripts/presets/keyconfig/keymap_data/blender_default.py | 4 ++-- .../presets/keyconfig/keymap_data/industry_compatible_data.py | 1 - scripts/startup/bl_ui/space_toolsystem_toolbar.py | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index 307b3687cbb..142c1a522ba 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5611,7 +5611,6 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), @@ -6783,10 +6782,11 @@ def km_3d_view_tool_cursor(params): def km_3d_view_tool_text_select(params): return ( - "3D View Tool: Text Select", + "3D View Tool: Edit Text, Select Text", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("font.selection_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ]}, ) diff --git a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index fb7d0f23126..f141566e7cc 100644 --- a/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3803,7 +3803,6 @@ def km_font(params): {"properties": [("delta", 1)]}), ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 981e7a73c2d..c52021e4b7b 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1269,7 +1269,7 @@ class _defs_edit_text: cursor='CROSSHAIR', icon="ops.generic.select_box", widget=None, - keymap=("3D View Tool: Text Select"), + keymap=(), ) -- 2.30.2 From dd504e60b442364d20728b9862a245be45c5b77d Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Fri, 21 Apr 2023 09:56:05 -0700 Subject: [PATCH 12/12] Use text cursor --- scripts/startup/bl_ui/space_toolsystem_toolbar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c52021e4b7b..2dd8b124ad3 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1266,7 +1266,7 @@ class _defs_edit_text: return dict( idname="builtin.select_text", label="Select Text", - cursor='CROSSHAIR', + cursor='TEXT', icon="ops.generic.select_box", widget=None, keymap=(), -- 2.30.2