56 if (
data ==
nullptr ||
data->runtime ==
nullptr) {
87 cursor_offset = std::clamp(cursor_offset, 0,
text->character_count);
89 int2 cursor_position{0, 0};
92 cursor_position.x = cursor_offset;
96 cursor_position.y += 1;
99 cursor_position.y = std::clamp(cursor_position.y, 0,
int(
text->lines.size() - 1));
100 cursor_position.x = std::clamp(
101 cursor_position.x, 0,
int(
text->lines[cursor_position.y].characters.size() - 1));
103 return cursor_position;
107 const int2 cursor_pos)
109 return text->lines[cursor_pos.y].characters[cursor_pos.x];
113 const int cursor_offset)
126 data->selection_start_offset = 0;
127 data->selection_end_offset = 0;
133 int sel_start_offset =
data->selection_start_offset;
134 int sel_end_offset =
data->selection_end_offset;
135 if (sel_start_offset > sel_end_offset) {
136 std::swap(sel_start_offset, sel_end_offset);
139 return IndexRange(sel_start_offset, sel_end_offset - sel_start_offset);
159 const int offset_start = char_start.
offset;
161 BLI_assert(offset_start >= 0 && offset_end <= data->text_len_bytes);
162 BLI_assert(offset_end >= 0 && offset_end <= data->text_len_bytes);
164 const int remaining =
data->text_len_bytes - offset_end;
166 std::memmove(
data->text_ptr + offset_start,
data->text_ptr + offset_end, remaining + 1);
167 data->text_len_bytes = offset_start + remaining;
195 {
LINE_BEGIN,
"LINE_BEGIN", 0,
"Line Begin",
""},
196 {
LINE_END,
"LINE_END", 0,
"Line End",
""},
197 {
TEXT_BEGIN,
"TEXT_BEGIN", 0,
"Text Begin",
""},
198 {
TEXT_END,
"TEXT_END", 0,
"Text End",
""},
199 {
PREV_CHAR,
"PREVIOUS_CHARACTER", 0,
"Previous Character",
""},
200 {
NEXT_CHAR,
"NEXT_CHARACTER", 0,
"Next Character",
""},
201 {
PREV_WORD,
"PREVIOUS_WORD", 0,
"Previous Word",
""},
202 {
NEXT_WORD,
"NEXT_WORD", 0,
"Next Word",
""},
203 {
PREV_LINE,
"PREVIOUS_LINE", 0,
"Previous Line",
""},
204 {
NEXT_LINE,
"NEXT_LINE", 0,
"Next Line",
""},
205 {0,
nullptr, 0,
nullptr,
nullptr},
212 if (cursor_position.x + offset > cur_line.
characters.size() - 1 &&
213 cursor_position.y <
text->lines.size() - 1)
215 cursor_position.x = 0;
219 else if (cursor_position.x + offset < 0 && cursor_position.y > 0) {
221 cursor_position.x =
text->lines[cursor_position.y].characters.size() - 1;
224 cursor_position.x += offset;
225 const int position_max =
text->lines[cursor_position.y].characters.size() - 1;
226 cursor_position.x = std::clamp(cursor_position.x, 0, position_max);
228 return cursor_position;
234 const int cur_pos_x = cur_line.
characters[cursor_position.x].position.x;
236 const int line_max =
text->lines.size() - 1;
237 const int new_line_index = std::clamp(cursor_position.y + offset, 0, line_max);
240 if (cursor_position.y == new_line_index) {
241 return cursor_position;
245 int best_distance = std::numeric_limits<int>::max();
246 int best_character_index = 0;
253 best_character_index =
i;
257 cursor_position.x = best_character_index;
258 cursor_position.y = new_line_index;
259 return cursor_position;
265 cursor_position.x = cur_line.
characters.size() - 1;
266 return cursor_position;
271 return ELEM(chr1,
' ',
'\t',
'\n') && !
ELEM(chr2,
' ',
'\t',
'\n');
276 const char *text_ptr)
280 while (cursor_position.x > 0 || cursor_position.y > 0) {
288 cursor_position = prev_cursor_pos;
290 return cursor_position;
295 const char *text_ptr)
297 const int maxline =
text->lines.size() - 1;
298 const int maxchar =
text->lines.last().characters.size() - 1;
300 while ((cursor_position.x < maxchar) || (cursor_position.y < maxline)) {
309 return cursor_position;
319 data->selection_start_offset =
data->cursor_offset;
338 cursor_position.x = 0;
344 cursor_position = {0, 0};
347 cursor_position.y =
text->lines.size() - 1;
360 data->selection_end_offset =
data->cursor_offset;
364 data->cursor_offset ==
data->selection_start_offset)
376 ot->name =
"Move Cursor";
377 ot->description =
"Move cursor in text";
378 ot->idname =
"SEQUENCER_OT_text_cursor_move";
393 "Where to move cursor to, to make a selection");
396 ot->srna,
"select_text",
false,
"Select Text",
"Select text while moving cursor");
407 size_t needed_size =
data->text_len_bytes + buf_len + 1;
412 std::memcpy(new_text,
data->text_ptr, cur_char.
offset);
413 std::memcpy(new_text + cur_char.
offset, buf, buf_len);
414 std::memcpy(new_text + cur_char.
offset + buf_len,
417 data->text_len_bytes += buf_len;
419 data->text_ptr = new_text;
421 data->cursor_offset += 1;
434 if (in_buf_len == 0) {
459 ot->name =
"Insert Character";
460 ot->description =
"Insert text at cursor position";
461 ot->idname =
"SEQUENCER_OT_text_insert";
473 ot->srna,
"string",
nullptr, 512,
"String",
"String to be inserted at cursor position");
478 {
DEL_NEXT_SEL,
"NEXT_OR_SELECTION", 0,
"Next or Selection",
""},
479 {
DEL_PREV_SEL,
"PREVIOUS_OR_SELECTION", 0,
"Previous or Selection",
""},
480 {0,
nullptr, 0,
nullptr,
nullptr},
485 const int offset_start = character.
offset;
487 BLI_assert(offset_start >= 0 && offset_start <= data->text_len_bytes);
488 BLI_assert(offset_end >= 0 && offset_end <= data->text_len_bytes);
489 const int remaining =
data->text_len_bytes - offset_end + 1;
490 std::memmove(
data->text_ptr + offset_start,
data->text_ptr + offset_end, remaining);
509 if (
data->cursor_offset >=
text->character_count) {
516 if (
data->cursor_offset == 0) {
521 data->cursor_offset -= 1;
531 ot->name =
"Delete Character";
532 ot->description =
"Delete text at cursor position";
533 ot->idname =
"SEQUENCER_OT_text_delete";
548 "Which part of the text to delete");
567 ot->name =
"Insert Line Break";
568 ot->description =
"Insert line break at cursor position";
569 ot->idname =
"SEQUENCER_OT_text_line_break";
583 data->selection_start_offset = 0;
584 data->selection_end_offset =
data->runtime->character_count;
592 ot->name =
"Select All";
593 ot->description =
"Select all characters";
594 ot->idname =
"SEQUENCER_OT_text_select_all";
624 ot->name =
"Deselect All";
625 ot->description =
"Deselect all characters";
626 ot->idname =
"SEQUENCER_OT_text_deselect_all";
653 ot->name =
"Edit Text";
654 ot->description =
"Toggle text editing";
655 ot->idname =
"SEQUENCER_OT_text_edit_mode_toggle";
668 int best_cursor_offset = 0;
669 float best_distance = std::numeric_limits<float>::max();
676 best_cursor_offset = character.
index;
681 return best_cursor_offset;
698 const float view_aspect = scene->
r.
xasp / scene->
r.
yasp;
704 mouse_loc.x /= view_aspect;
706 mouse_loc -= view_offs;
717 bool make_selection =
false;
719 switch (event->
type) {
723 if (make_selection) {
724 data->selection_end_offset =
data->cursor_offset;
733 make_selection =
true;
735 data->selection_start_offset =
data->cursor_offset;
738 data->selection_end_offset =
data->cursor_offset;
779 ot->name =
"Set Cursor";
780 ot->description =
"Set cursor position in text";
781 ot->idname =
"SEQUENCER_OT_text_cursor_set";
794 ot->srna,
"select_text",
false,
"Select Text",
"Select text while moving cursor");
805 const int offset_start = start.
offset;
807 BLI_assert(offset_start >= 0 && offset_start <= data->text_len_bytes);
808 BLI_assert(offset_end >= 0 && offset_end <= data->text_len_bytes);
811 const size_t len = offset_end - offset_start;
813 memcpy(buf,
data->text_ptr + offset_start,
len);
836 ot->name =
"Copy Text";
837 ot->description =
"Copy text to clipboard";
838 ot->idname =
"SEQUENCER_OT_text_edit_copy";
862 size_t needed_size =
data->text_len_bytes + buf_len + 1;
867 std::memcpy(new_text,
data->text_ptr, cur_char.
offset);
868 std::memcpy(new_text + cur_char.
offset, buf, buf_len);
869 std::memcpy(new_text + cur_char.
offset + buf_len,
872 data->text_len_bytes += buf_len;
874 data->text_ptr = new_text;
886 ot->name =
"Paste Text";
887 ot->description =
"Paste text from clipboard";
888 ot->idname =
"SEQUENCER_OT_text_edit_paste";
917 ot->name =
"Cut Text";
918 ot->description =
"Cut text to clipboard";
919 ot->idname =
"SEQUENCER_OT_text_edit_cut";
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
Scene * CTX_data_sequencer_scene(const bContext *C)
float BKE_scene_frame_get(const Scene *scene)
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
int BLI_str_utf8_size_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_strlen_utf8(const char *strc) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
struct TextVarsRuntime TextVarsRuntime
@ SEQ_FLAG_TEXT_EDITING_ACTIVE
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
View2D * UI_view2d_fromcontext(const bContext *C)
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
BMesh const char void * data
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr bool is_empty() const
float distance(VecOp< float, D >, VecOp< float, D >) RET
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
blender::IndexRange strip_text_selection_range_get(const TextVars *data)
static void delete_character(const seq::CharInfo character, TextVars *data)
void SEQUENCER_OT_text_edit_copy(wmOperatorType *ot)
void SEQUENCER_OT_text_line_break(wmOperatorType *ot)
static bool text_insert(TextVars *data, const char *buf, const size_t buf_len)
static void cursor_set_by_mouse_position(const bContext *C, const wmEvent *event)
static wmOperatorStatus sequencer_text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int2 cursor_move_next_word(int2 cursor_position, const TextVarsRuntime *text, const char *text_ptr)
void SEQUENCER_OT_text_delete(wmOperatorType *ot)
void SEQUENCER_OT_text_edit_cut(wmOperatorType *ot)
static const EnumPropertyItem move_type_items[]
bool sequencer_text_editing_active_poll(bContext *C)
static wmOperatorStatus sequencer_text_edit_mode_toggle_exec(bContext *C, wmOperator *)
static const EnumPropertyItem delete_type_items[]
static wmOperatorStatus sequencer_text_edit_paste_exec(bContext *C, wmOperator *)
void SEQUENCER_OT_text_insert(wmOperatorType *ot)
void SEQUENCER_OT_text_deselect_all(wmOperatorType *ot)
bool sequencer_editing_initialized_and_active(bContext *C)
static wmOperatorStatus sequencer_text_edit_copy_exec(bContext *C, wmOperator *)
static int2 cursor_move_by_line(int2 cursor_position, const TextVarsRuntime *text, int offset)
static void text_editing_update(const bContext *C)
static const seq::CharInfo & character_at_cursor_offset_get(const TextVarsRuntime *text, const int cursor_offset)
void SEQUENCER_OT_text_select_all(wmOperatorType *ot)
static wmOperatorStatus sequencer_text_deselect_all_exec(bContext *C, wmOperator *)
static int2 cursor_move_line_end(int2 cursor_position, const TextVarsRuntime *text)
static bool sequencer_text_editing_poll(bContext *C)
static wmOperatorStatus sequencer_text_cursor_move_exec(bContext *C, wmOperator *op)
static int2 cursor_move_prev_word(int2 cursor_position, const TextVarsRuntime *text, const char *text_ptr)
static wmOperatorStatus sequencer_text_cursor_set_invoke(bContext *C, wmOperator *op, const wmEvent *event)
blender::int2 strip_text_cursor_offset_to_position(const TextVarsRuntime *text, int cursor_offset)
static wmOperatorStatus sequencer_text_delete_exec(bContext *C, wmOperator *op)
static void text_selection_cancel(TextVars *data)
static bool is_whitespace_transition(char chr1, char chr2)
static wmOperatorStatus sequencer_text_insert_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_text_edit_paste(wmOperatorType *ot)
static void delete_selected_text(TextVars *data)
static int cursor_position_to_offset(const TextVarsRuntime *text, int2 cursor_position)
bool strip_point_image_isect(const Scene *scene, const Strip *strip, float point_view[2])
static const seq::CharInfo & character_at_cursor_pos_get(const TextVarsRuntime *text, const int2 cursor_pos)
static bool text_has_selection(const TextVars *data)
void SEQUENCER_OT_text_cursor_move(wmOperatorType *ot)
static int find_closest_cursor_offset(const TextVars *data, float2 mouse_loc)
static wmOperatorStatus sequencer_text_edit_cut_exec(bContext *C, wmOperator *)
static wmOperatorStatus sequencer_text_select_all_exec(bContext *C, wmOperator *)
static void text_edit_copy(const TextVars *data)
static wmOperatorStatus sequencer_text_line_break_exec(bContext *C, wmOperator *)
static int2 cursor_move_by_character(int2 cursor_position, const TextVarsRuntime *text, int offset)
void SEQUENCER_OT_text_cursor_set(wmOperatorType *ot)
void SEQUENCER_OT_text_edit_mode_toggle(wmOperatorType *ot)
static wmOperatorStatus sequencer_text_cursor_set_modal(bContext *C, wmOperator *, const wmEvent *event)
T distance(const T &a, const T &b)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
float3x3 image_transform_matrix_get(const Scene *scene, const Strip *strip)
void relations_invalidate_cache_raw(Scene *scene, Strip *strip)
Strip * select_active_get(const Scene *scene)
bool time_strip_intersects_frame(const Scene *scene, const Strip *strip, const int timeline_frame)
bool effects_can_render_text(const Strip *strip)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Vector< CharInfo > characters
void WM_event_drag_start_mval(const wmEvent *event, const ARegion *region, int r_mval[2])
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_clipboard_text_set(const char *buf, bool selection)
char * WM_clipboard_text_get(bool selection, bool ensure_utf8, int *r_len)