BLI: New functions specifically for word/sequence selection #107927
|
@ -42,6 +42,24 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
|
|||
eStrCursorJumpType jump,
|
||||
bool use_init_step);
|
||||
|
||||
|
||||
/**
|
||||
* Word/Sequence Selection. Given a position within a string, return the start and end of the
|
||||
* closest sequence of delimited characters. Generally a word, but could be a sequence of spaces.
|
||||
*
|
||||
* \param str: The string with a cursor position
|
||||
* \param str_maxlen: The maximum characters to consider
|
||||
* \param pos: The starting cursor position (probably moved on completion)
|
||||
* \param r_start: returned start of word/sequence boundary (0-based)
|
||||
* \param r_end: returned end of word/sequence boundary (0-based)
|
||||
*/
|
||||
|
||||
void BLI_str_cursor_step_bounds_utf8(
|
||||
const char *str, const size_t str_maxlen, int *pos, int *r_start, int *r_end);
|
||||
|
||||
void BLI_str_cursor_step_bounds_utf32(
|
||||
const char32_t *str, const size_t str_maxlen, int *pos, int *r_start, int *r_end);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -314,3 +314,52 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
|
|||
BLI_assert_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_str_cursor_step_bounds_utf8(
|
||||
const char *str, const size_t str_maxlen, int *pos, int *start, int *end)
|
||||
{
|
||||
/* What type of characters are on either side of the current cursor position? */
|
||||
const eStrCursorDelimType prev = (*pos > 0) ? cursor_delim_type_utf8(str, str_maxlen, *pos - 1) :
|
||||
STRCUR_DELIM_NONE;
|
||||
const eStrCursorDelimType next = (*pos < str_maxlen) ?
|
||||
cursor_delim_type_utf8(str, str_maxlen, *pos) :
|
||||
STRCUR_DELIM_NONE;
|
||||
*start = *pos;
|
||||
*end = *pos;
|
||||
|
||||
if (prev == next || ELEM(next, STRCUR_DELIM_WHITESPACE, STRCUR_DELIM_NONE)) {
|
||||
/* Expand backward if we are between similar content, before whitespace, or at end. */
|
||||
BLI_str_cursor_step_utf8(str, str_maxlen, start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false);
|
||||
}
|
||||
if (prev == next || ELEM(prev, STRCUR_DELIM_WHITESPACE, STRCUR_DELIM_NONE)) {
|
||||
/* Expand forward if we are between similar content, after whitespace, or at beginning. */
|
||||
BLI_str_cursor_step_utf8(str, str_maxlen, end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false);
|
||||
}
|
||||
|
||||
/* Move cursor position to the end of selection. */
|
||||
*pos = *end;
|
||||
}
|
||||
|
||||
void BLI_str_cursor_step_bounds_utf32(
|
||||
const char32_t *str, const size_t str_maxlen, int *pos, int *start, int *end)
|
||||
{
|
||||
/* What type of characters are on either side of the current cursor position? */
|
||||
const eStrCursorDelimType prev = (*pos > 0) ? cursor_delim_type_unicode(str[*pos - 1]) :
|
||||
STRCUR_DELIM_NONE;
|
||||
const eStrCursorDelimType next = (*pos < str_maxlen) ? cursor_delim_type_unicode(str[*pos]) :
|
||||
STRCUR_DELIM_NONE;
|
||||
*start = *pos;
|
||||
*end = *pos;
|
||||
|
||||
if (prev == next || ELEM(next, STRCUR_DELIM_WHITESPACE, STRCUR_DELIM_NONE)) {
|
||||
/* Expand backward if we are between similar content, before whitespace, or at end. */
|
||||
BLI_str_cursor_step_utf32(str, str_maxlen, start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false);
|
||||
}
|
||||
if (prev == next || ELEM(prev, STRCUR_DELIM_WHITESPACE, STRCUR_DELIM_NONE)) {
|
||||
/* Expand forward if we are between similar content, after whitespace, or at beginning. */
|
||||
BLI_str_cursor_step_utf32(str, str_maxlen, end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false);
|
||||
}
|
||||
|
||||
/* Move cursor position to the end of selection. */
|
||||
*pos = *end;
|
||||
}
|
||||
|
|
|
@ -1920,9 +1920,18 @@ void FONT_OT_selection_set(struct wmOperatorType *ot)
|
|||
|
||||
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);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
BLI_str_cursor_step_bounds_utf32(ef->textbuf, ef->len, &ef->pos, &ef->selstart, &ef->selend);
|
||||
|
||||
/* XXX: Text object selection start is 1-based, unlike text processing elsewhere in Blender. */
|
||||
ef->selstart += 1;
|
||||
|
||||
font_select_update_primary_clipboard(obedit);
|
||||
text_update_edited(C, obedit, FO_CURS);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
|
|
@ -3730,8 +3730,12 @@ static void ui_do_but_textedit(
|
|||
|
||||
/* only select a word in button if there was no selection before */
|
||||
if (event->val == KM_DBL_CLICK && had_selection == false) {
|
||||
ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_DELIM);
|
||||
ui_textedit_move(but, data, STRCUR_DIR_NEXT, true, STRCUR_JUMP_DELIM);
|
||||
int pos = (int)but->pos;
|
||||
int selsta, selend;
|
||||
BLI_str_cursor_step_bounds_utf8(data->str, strlen(data->str), &pos, &selsta, &selend);
|
||||
but->pos = (short)pos;
|
||||
but->selsta = (short)selsta;
|
||||
but->selend = (short)selend;
|
||||
retval = WM_UI_HANDLER_BREAK;
|
||||
changed = true;
|
||||
}
|
||||
|
|
|
@ -1258,9 +1258,7 @@ static int console_selectword_invoke(bContext *C, wmOperator *UNUSED(op), const
|
|||
if (console_line_column_from_index(sc, pos, &cl, &offset, &n)) {
|
||||
int sel[2] = {n, n};
|
||||
|
||||
BLI_str_cursor_step_utf8(cl->line, cl->len, &sel[0], STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
|
||||
|
||||
BLI_str_cursor_step_utf8(cl->line, cl->len, &sel[1], STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
|
||||
BLI_str_cursor_step_bounds_utf8(cl->line, cl->len, &n, &sel[0], &sel[1]);
|
||||
|
||||
sel[0] = offset - sel[0];
|
||||
sel[1] = offset - sel[1];
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_string_cursor_utf8.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
|
@ -1577,11 +1578,9 @@ void TEXT_OT_select_line(wmOperatorType *ot)
|
|||
static int text_select_word_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
/* don't advance cursor before stepping */
|
||||
const bool use_init_step = false;
|
||||
|
||||
txt_jump_left(text, false, use_init_step);
|
||||
txt_jump_right(text, true, use_init_step);
|
||||
BLI_str_cursor_step_bounds_utf8(
|
||||
text->curl->line, text->curl->len, &text->selc, &text->curc, &text->selc);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_select_update_primary_clipboard(text);
|
||||
|
|
Loading…
Reference in New Issue