276 #ifndef INCLUDE_STB_TEXTEDIT_H
277 #define INCLUDE_STB_TEXTEDIT_H
288 #ifndef STB_TEXTEDIT_UNDOSTATECOUNT
289 #define STB_TEXTEDIT_UNDOSTATECOUNT 99
291 #ifndef STB_TEXTEDIT_UNDOCHARCOUNT
292 #define STB_TEXTEDIT_UNDOCHARCOUNT 999
294 #ifndef STB_TEXTEDIT_CHARTYPE
295 #define STB_TEXTEDIT_CHARTYPE int
297 #ifndef STB_TEXTEDIT_POSITIONTYPE
298 #define STB_TEXTEDIT_POSITIONTYPE int
369 #endif //INCLUDE_STB_TEXTEDIT_H
382 #ifdef STB_TEXTEDIT_IMPLEMENTATION
384 #ifndef STB_TEXTEDIT_memmove
386 #define STB_TEXTEDIT_memmove memmove
400 float base_y = 0, prev_x;
410 if (
r.num_chars <= 0)
413 if (
i==0 &&
y < base_y +
r.ymin)
416 if (
y < base_y +
r.ymax)
420 base_y +=
r.baseline_y_delta;
435 for (k=0; k <
r.num_chars; ++k) {
450 return i+
r.num_chars-1;
452 return i+
r.num_chars;
490 p = stb_text_locate_coord(
str,
x,
y);
529 find->first_char = 0;
531 find->height =
r.ymax -
r.ymin;
542 find->first_char =
i;
544 find->prev_first = prev_start;
554 if (
n <
i +
r.num_chars)
558 find->y +=
r.baseline_y_delta;
561 find->first_char =
first =
i;
562 find->length =
r.num_chars;
563 find->height =
r.ymax -
r.ymin;
564 find->prev_first = prev_start;
572 #define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
578 if (STB_TEXT_HAS_SELECTION(state)) {
591 stb_text_makeundo_delete(
str, state, where,
len);
599 stb_textedit_clamp(
str, state);
600 if (STB_TEXT_HAS_SELECTION(state)) {
625 if (STB_TEXT_HAS_SELECTION(state)) {
626 stb_textedit_sortselection(state);
636 if (STB_TEXT_HAS_SELECTION(state)) {
637 stb_textedit_sortselection(state);
638 stb_textedit_clamp(
str, state);
645 #ifdef STB_TEXTEDIT_IS_SPACE
651 #ifndef STB_TEXTEDIT_MOVEWORDLEFT
655 while( c >= 0 && !is_word_boundary(
str, c ) )
663 #define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous
666 #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
671 while( c <
len && !is_word_boundary(
str, c ) )
679 #define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next
687 if (!STB_TEXT_HAS_SELECTION(state))
696 if (STB_TEXT_HAS_SELECTION(state)) {
697 stb_textedit_delete_selection(
str,state);
708 stb_textedit_clamp(
str, state);
709 stb_textedit_delete_selection(
str,state);
712 stb_text_makeundo_insert(state, state->
cursor,
len);
723 #ifndef STB_TEXTEDIT_KEYTYPE
724 #define STB_TEXTEDIT_KEYTYPE int
742 stb_text_makeundo_replace(
str, state, state->
cursor, 1, 1);
749 stb_textedit_delete_selection(
str,state);
751 stb_text_makeundo_insert(state, state->
cursor, 1);
760 #ifdef STB_TEXTEDIT_K_INSERT
761 case STB_TEXTEDIT_K_INSERT:
767 stb_text_undo(
str, state);
772 stb_text_redo(
str, state);
778 if (STB_TEXT_HAS_SELECTION(state))
779 stb_textedit_move_to_first(state);
788 if (STB_TEXT_HAS_SELECTION(state))
789 stb_textedit_move_to_last(
str, state);
792 stb_textedit_clamp(
str, state);
797 stb_textedit_clamp(
str, state);
798 stb_textedit_prep_selection_at_cursor(state);
806 #ifdef STB_TEXTEDIT_MOVEWORDLEFT
808 if (STB_TEXT_HAS_SELECTION(state))
809 stb_textedit_move_to_first(state);
812 stb_textedit_clamp(
str, state );
817 if( !STB_TEXT_HAS_SELECTION( state ) )
818 stb_textedit_prep_selection_at_cursor(state);
823 stb_textedit_clamp(
str, state );
827 #ifdef STB_TEXTEDIT_MOVEWORDRIGHT
829 if (STB_TEXT_HAS_SELECTION(state))
830 stb_textedit_move_to_last(
str, state);
833 stb_textedit_clamp(
str, state );
838 if( !STB_TEXT_HAS_SELECTION( state ) )
839 stb_textedit_prep_selection_at_cursor(state);
844 stb_textedit_clamp(
str, state );
849 stb_textedit_prep_selection_at_cursor(state);
852 stb_textedit_clamp(
str, state);
870 stb_textedit_prep_selection_at_cursor(state);
871 else if (STB_TEXT_HAS_SELECTION(state))
872 stb_textedit_move_to_last(
str,state);
875 stb_textedit_clamp(
str, state);
882 int start = find.first_char + find.length;
888 #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
897 stb_textedit_clamp(
str, state);
921 stb_textedit_prep_selection_at_cursor(state);
922 else if (STB_TEXT_HAS_SELECTION(state))
923 stb_textedit_move_to_first(state);
926 stb_textedit_clamp(
str, state);
930 if (find.prev_first != find.first_char) {
934 state->
cursor = find.prev_first;
939 #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
948 stb_textedit_clamp(
str, state);
961 if (STB_TEXT_HAS_SELECTION(state))
962 stb_textedit_delete_selection(
str, state);
966 stb_textedit_delete(
str, state, state->
cursor, 1);
973 if (STB_TEXT_HAS_SELECTION(state))
974 stb_textedit_delete_selection(
str, state);
976 stb_textedit_clamp(
str, state);
978 stb_textedit_delete(
str, state, state->
cursor-1, 1);
985 #ifdef STB_TEXTEDIT_K_TEXTSTART2
986 case STB_TEXTEDIT_K_TEXTSTART2:
993 #ifdef STB_TEXTEDIT_K_TEXTEND2
994 case STB_TEXTEDIT_K_TEXTEND2:
1002 #ifdef STB_TEXTEDIT_K_TEXTSTART2
1006 stb_textedit_prep_selection_at_cursor(state);
1011 #ifdef STB_TEXTEDIT_K_TEXTEND2
1015 stb_textedit_prep_selection_at_cursor(state);
1021 #ifdef STB_TEXTEDIT_K_LINESTART2
1022 case STB_TEXTEDIT_K_LINESTART2:
1025 stb_textedit_clamp(
str, state);
1026 stb_textedit_move_to_first(state);
1034 #ifdef STB_TEXTEDIT_K_LINEEND2
1035 case STB_TEXTEDIT_K_LINEEND2:
1039 stb_textedit_clamp(
str, state);
1040 stb_textedit_move_to_first(state);
1049 #ifdef STB_TEXTEDIT_K_LINESTART2
1053 stb_textedit_clamp(
str, state);
1054 stb_textedit_prep_selection_at_cursor(state);
1063 #ifdef STB_TEXTEDIT_K_LINEEND2
1068 stb_textedit_clamp(
str, state);
1069 stb_textedit_prep_selection_at_cursor(state);
1091 static void stb_textedit_flush_redo(
StbUndoState *state)
1098 static void stb_textedit_discard_undo(
StbUndoState *state)
1120 static void stb_textedit_discard_redo(
StbUndoState *state)
1139 const char* buf_begin = (
char*)state->
undo_rec; (
void)buf_begin;
1153 stb_textedit_flush_redo(state);
1158 stb_textedit_discard_undo(state);
1169 stb_textedit_discard_undo(state);
1176 StbUndoRecord *
r = stb_text_create_undo_record(state, insert_len);
1184 if (insert_len == 0) {
1185 r->char_storage = -1;
1198 if (
s->undo_point == 0)
1202 u =
s->undo_rec[
s->undo_point-1];
1203 r = &
s->undo_rec[
s->redo_point-1];
1204 r->char_storage = -1;
1223 r->insert_length = 0;
1233 stb_textedit_discard_redo(s);
1235 r = &
s->undo_rec[
s->redo_point-1];
1270 u = &
s->undo_rec[
s->undo_point];
1271 r =
s->undo_rec[
s->redo_point];
1281 if (
r.delete_length) {
1301 if (
r.insert_length) {
1304 s->redo_char_point +=
r.insert_length;
1307 state->
cursor =
r.where +
r.insert_length;
1333 for (
i=0;
i < old_length; ++
i)
1339 static void stb_textedit_clear_state(
STB_TexteditState *state,
int is_single_line)
1351 state->
single_line = (
unsigned char) is_single_line;
1356 static void stb_textedit_initialize_state(
STB_TexteditState *state,
int is_single_line)
1358 stb_textedit_clear_state(state, is_single_line);
1361 #if defined(__GNUC__) || defined(__clang__)
1362 #pragma GCC diagnostic push
1363 #pragma GCC diagnostic ignored "-Wcast-qual"
1371 #if defined(__GNUC__) || defined(__clang__)
1372 #pragma GCC diagnostic pop
1375 #endif//STB_TEXTEDIT_IMPLEMENTATION