Lines Matching refs:state
14 // selection state, and undo state.
79 // state of a text widget (except for the string, which you will store
179 // be a bitflag, so we can test the shifted state of cursor movements to allow selection,
197 // Each textfield keeps its own insert mode state, which is not how normal
203 // void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line)
205 // void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
206 // void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
207 // int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
208 // int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
209 // void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
212 // state.
215 // set the textedit state to a known good default state when initially
247 // When rendering, you can read the cursor position and selection state from
284 // per-textfield; it includes cursor position, selection state,
285 // and undo state.
337 // each textfield keeps its own insert mode state. to keep an app-wide
338 // insert mode, copy this value in/out of the app state
456 static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
460 if( state->single_line )
467 state->cursor = stb_text_locate_coord(str, x, y);
468 state->select_start = state->cursor;
469 state->select_end = state->cursor;
470 state->has_preferred_x = 0;
474 static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
480 if( state->single_line )
487 if (state->select_start == state->select_end)
488 state->select_start = state->cursor;
491 state->cursor = state->select_end = p;
500 static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
501 static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
502 static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
503 static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
504 static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
574 // make the selection/cursor state valid if client altered the string
575 static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
578 if (STB_TEXT_HAS_SELECTION(state)) {
579 if (state->select_start > n) state->select_start = n;
580 if (state->select_end > n) state->select_end = n;
582 if (state->select_start == state->select_end)
583 state->cursor = state->select_start;
585 if (state->cursor > n) state->cursor = n;
589 static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
591 stb_text_makeundo_delete(str, state, where, len);
593 state->has_preferred_x = 0;
597 static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
599 stb_textedit_clamp(str, state);
600 if (STB_TEXT_HAS_SELECTION(state)) {
601 if (state->select_start < state->select_end) {
602 stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start);
603 state->select_end = state->cursor = state->select_start;
605 stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end);
606 state->select_start = state->cursor = state->select_end;
608 state->has_preferred_x = 0;
613 static void stb_textedit_sortselection(STB_TexteditState *state)
615 if (state->select_end < state->select_start) {
616 int temp = state->select_end;
617 state->select_end = state->select_start;
618 state->select_start = temp;
623 static void stb_textedit_move_to_first(STB_TexteditState *state)
625 if (STB_TEXT_HAS_SELECTION(state)) {
626 stb_textedit_sortselection(state);
627 state->cursor = state->select_start;
628 state->select_end = state->select_start;
629 state->has_preferred_x = 0;
634 static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
636 if (STB_TEXT_HAS_SELECTION(state)) {
637 stb_textedit_sortselection(state);
638 stb_textedit_clamp(str, state);
639 state->cursor = state->select_end;
640 state->select_start = state->select_end;
641 state->has_preferred_x = 0;
685 static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
687 if (!STB_TEXT_HAS_SELECTION(state))
688 state->select_start = state->select_end = state->cursor;
690 state->cursor = state->select_end;
694 static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
696 if (STB_TEXT_HAS_SELECTION(state)) {
697 stb_textedit_delete_selection(str,state); // implicitly clamps
698 state->has_preferred_x = 0;
705 static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
708 stb_textedit_clamp(str, state);
709 stb_textedit_delete_selection(str,state);
711 if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
712 stb_text_makeundo_insert(state, state->cursor, len);
713 state->cursor += len;
714 state->has_preferred_x = 0;
718 if (state->undostate.undo_point)
719 --state->undostate.undo_point;
728 static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
738 if (c == '\n' && state->single_line)
741 if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
742 stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
743 STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
744 if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
745 ++state->cursor;
746 state->has_preferred_x = 0;
749 stb_textedit_delete_selection(str,state); // implicitly clamps
750 if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
751 stb_text_makeundo_insert(state, state->cursor, 1);
752 ++state->cursor;
753 state->has_preferred_x = 0;
762 state->insert_mode = !state->insert_mode;
767 stb_text_undo(str, state);
768 state->has_preferred_x = 0;
772 stb_text_redo(str, state);
773 state->has_preferred_x = 0;
778 if (STB_TEXT_HAS_SELECTION(state))
779 stb_textedit_move_to_first(state);
781 if (state->cursor > 0)
782 --state->cursor;
783 state->has_preferred_x = 0;
788 if (STB_TEXT_HAS_SELECTION(state))
789 stb_textedit_move_to_last(str, state);
791 ++state->cursor;
792 stb_textedit_clamp(str, state);
793 state->has_preferred_x = 0;
797 stb_textedit_clamp(str, state);
798 stb_textedit_prep_selection_at_cursor(state);
800 if (state->select_end > 0)
801 --state->select_end;
802 state->cursor = state->select_end;
803 state->has_preferred_x = 0;
808 if (STB_TEXT_HAS_SELECTION(state))
809 stb_textedit_move_to_first(state);
811 state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
812 stb_textedit_clamp( str, state );
817 if( !STB_TEXT_HAS_SELECTION( state ) )
818 stb_textedit_prep_selection_at_cursor(state);
820 state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
821 state->select_end = state->cursor;
823 stb_textedit_clamp( str, state );
829 if (STB_TEXT_HAS_SELECTION(state))
830 stb_textedit_move_to_last(str, state);
832 state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
833 stb_textedit_clamp( str, state );
838 if( !STB_TEXT_HAS_SELECTION( state ) )
839 stb_textedit_prep_selection_at_cursor(state);
841 state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
842 state->select_end = state->cursor;
844 stb_textedit_clamp( str, state );
849 stb_textedit_prep_selection_at_cursor(state);
851 ++state->select_end;
852 stb_textedit_clamp(str, state);
853 state->cursor = state->select_end;
854 state->has_preferred_x = 0;
863 if (state->single_line) {
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);
876 stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
880 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
883 state->cursor = start;
884 STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
895 ++state->cursor;
897 stb_textedit_clamp(str, state);
899 state->has_preferred_x = 1;
900 state->preferred_x = goal_x;
903 state->select_end = state->cursor;
914 if (state->single_line) {
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);
927 stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
932 float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
934 state->cursor = find.prev_first;
935 STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
946 ++state->cursor;
948 stb_textedit_clamp(str, state);
950 state->has_preferred_x = 1;
951 state->preferred_x = goal_x;
954 state->select_end = state->cursor;
961 if (STB_TEXT_HAS_SELECTION(state))
962 stb_textedit_delete_selection(str, state);
965 if (state->cursor < n)
966 stb_textedit_delete(str, state, state->cursor, 1);
968 state->has_preferred_x = 0;
973 if (STB_TEXT_HAS_SELECTION(state))
974 stb_textedit_delete_selection(str, state);
976 stb_textedit_clamp(str, state);
977 if (state->cursor > 0) {
978 stb_textedit_delete(str, state, state->cursor-1, 1);
979 --state->cursor;
982 state->has_preferred_x = 0;
989 state->cursor = state->select_start = state->select_end = 0;
990 state->has_preferred_x = 0;
997 state->cursor = STB_TEXTEDIT_STRINGLEN(str);
998 state->select_start = state->select_end = 0;
999 state->has_preferred_x = 0;
1006 stb_textedit_prep_selection_at_cursor(state);
1007 state->cursor = state->select_end = 0;
1008 state->has_preferred_x = 0;
1015 stb_textedit_prep_selection_at_cursor(state);
1016 state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
1017 state->has_preferred_x = 0;
1025 stb_textedit_clamp(str, state);
1026 stb_textedit_move_to_first(state);
1027 if (state->single_line)
1028 state->cursor = 0;
1029 else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
1030 --state->cursor;
1031 state->has_preferred_x = 0;
1039 stb_textedit_clamp(str, state);
1040 stb_textedit_move_to_first(state);
1041 if (state->single_line)
1042 state->cursor = n;
1043 else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
1044 ++state->cursor;
1045 state->has_preferred_x = 0;
1053 stb_textedit_clamp(str, state);
1054 stb_textedit_prep_selection_at_cursor(state);
1055 if (state->single_line)
1056 state->cursor = 0;
1057 else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
1058 --state->cursor;
1059 state->select_end = state->cursor;
1060 state->has_preferred_x = 0;
1068 stb_textedit_clamp(str, state);
1069 stb_textedit_prep_selection_at_cursor(state);
1070 if (state->single_line)
1071 state->cursor = n;
1072 else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
1073 ++state->cursor;
1074 state->select_end = state->cursor;
1075 state->has_preferred_x = 0;
1091 static void stb_textedit_flush_redo(StbUndoState *state)
1093 state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
1094 state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
1098 static void stb_textedit_discard_undo(StbUndoState *state)
1100 if (state->undo_point > 0) {
1101 // if the 0th undo state has characters, clean those up
1102 if (state->undo_rec[0].char_storage >= 0) {
1103 int n = state->undo_rec[0].insert_length, i;
1105 state->undo_char_point -= n;
1106 STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
1107 for (i=0; i < state->undo_point; ++i)
1108 if (state->undo_rec[i].char_storage >= 0)
1109 state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
1111 --state->undo_point;
1112 STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
1120 static void stb_textedit_discard_redo(StbUndoState *state)
1124 if (state->redo_point <= k) {
1125 // if the k'th undo state has characters, clean those up
1126 if (state->undo_rec[k].char_storage >= 0) {
1127 int n = state->undo_rec[k].insert_length, i;
1129 state->redo_char_point += n;
1130 STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
1132 for (i=state->redo_point; i < k; ++i)
1133 if (state->undo_rec[i].char_storage >= 0)
1134 state->undo_rec[i].char_storage += n;
1138 size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
1139 const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
1140 const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
1141 IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
1142 IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
1143 STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
1146 ++state->redo_point;
1150 static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars)
1153 stb_textedit_flush_redo(state);
1157 if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
1158 stb_textedit_discard_undo(state);
1162 state->undo_point = 0;
1163 state->undo_char_point = 0;
1168 while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
1169 stb_textedit_discard_undo(state);
1171 return &state->undo_rec[state->undo_point++];
1174 static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
1176 StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
1188 r->char_storage = state->undo_char_point;
1189 state->undo_char_point += insert_len;
1190 return &state->undo_char[r->char_storage];
1194 static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
1196 StbUndoState *s = &state->undostate;
1256 state->cursor = u.where + u.insert_length;
1262 static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
1264 StbUndoState *s = &state->undostate;
1307 state->cursor = r.where + r.insert_length;
1313 static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length)
1315 stb_text_createundo(&state->undostate, where, 0, length);
1318 static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
1321 STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
1328 static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
1331 STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
1338 // reset the state to default
1339 static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line)
1341 state->undostate.undo_point = 0;
1342 state->undostate.undo_char_point = 0;
1343 state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
1344 state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
1345 state->select_end = state->select_start = 0;
1346 state->cursor = 0;
1347 state->has_preferred_x = 0;
1348 state->preferred_x = 0;
1349 state->cursor_at_end_of_line = 0;
1350 state->initialized = 1;
1351 state->single_line = (unsigned char) is_single_line;
1352 state->insert_mode = 0;
1356 static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line)
1358 stb_textedit_clear_state(state, is_single_line);
1366 static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
1368 return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);