|
@@ -1,10 +1,12 @@
|
|
|
// [DEAR IMGUI]
|
|
// [DEAR IMGUI]
|
|
|
-// This is a slightly modified version of stb_textedit.h 1.13.
|
|
|
|
|
|
|
+// This is a slightly modified version of stb_textedit.h 1.14.
|
|
|
// Those changes would need to be pushed into nothings/stb:
|
|
// Those changes would need to be pushed into nothings/stb:
|
|
|
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
|
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
|
|
|
|
+// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
|
|
// Grep for [DEAR IMGUI] to find the changes.
|
|
// Grep for [DEAR IMGUI] to find the changes.
|
|
|
|
|
+// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
|
|
|
|
|
|
|
-// stb_textedit.h - v1.13 - public domain - Sean Barrett
|
|
|
|
|
|
|
+// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
|
|
// Development of this library was sponsored by RAD Game Tools
|
|
// Development of this library was sponsored by RAD Game Tools
|
|
|
//
|
|
//
|
|
|
// This C header file implements the guts of a multi-line text-editing
|
|
// This C header file implements the guts of a multi-line text-editing
|
|
@@ -19,7 +21,7 @@
|
|
|
// texts, as its performance does not scale and it has limited undo).
|
|
// texts, as its performance does not scale and it has limited undo).
|
|
|
//
|
|
//
|
|
|
// Non-trivial behaviors are modelled after Windows text controls.
|
|
// Non-trivial behaviors are modelled after Windows text controls.
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
//
|
|
//
|
|
|
// LICENSE
|
|
// LICENSE
|
|
|
//
|
|
//
|
|
@@ -29,12 +31,13 @@
|
|
|
// DEPENDENCIES
|
|
// DEPENDENCIES
|
|
|
//
|
|
//
|
|
|
// Uses the C runtime function 'memmove', which you can override
|
|
// Uses the C runtime function 'memmove', which you can override
|
|
|
-// by defining STB_TEXTEDIT_memmove before the implementation.
|
|
|
|
|
|
|
+// by defining IMSTB_TEXTEDIT_memmove before the implementation.
|
|
|
// Uses no other functions. Performs no runtime allocations.
|
|
// Uses no other functions. Performs no runtime allocations.
|
|
|
//
|
|
//
|
|
|
//
|
|
//
|
|
|
// VERSION HISTORY
|
|
// VERSION HISTORY
|
|
|
//
|
|
//
|
|
|
|
|
+// 1.14 (2021-07-11) page up/down, various fixes
|
|
|
// 1.13 (2019-02-07) fix bug in undo size management
|
|
// 1.13 (2019-02-07) fix bug in undo size management
|
|
|
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
|
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
|
|
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
|
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
|
@@ -58,6 +61,7 @@
|
|
|
// Ulf Winklemann: move-by-word in 1.1
|
|
// Ulf Winklemann: move-by-word in 1.1
|
|
|
// Fabian Giesen: secondary key inputs in 1.5
|
|
// Fabian Giesen: secondary key inputs in 1.5
|
|
|
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
|
|
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
|
|
|
|
|
+// Louis Schnellbach: page up/down in 1.14
|
|
|
//
|
|
//
|
|
|
// Bugfixes:
|
|
// Bugfixes:
|
|
|
// Scott Graham
|
|
// Scott Graham
|
|
@@ -93,8 +97,8 @@
|
|
|
// moderate sizes. The undo system does no memory allocations, so
|
|
// moderate sizes. The undo system does no memory allocations, so
|
|
|
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
|
|
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
|
|
|
//
|
|
//
|
|
|
-// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT
|
|
|
|
|
-// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT
|
|
|
|
|
|
|
+// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATECOUNT
|
|
|
|
|
+// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHARCOUNT
|
|
|
//
|
|
//
|
|
|
//
|
|
//
|
|
|
// Implementation mode:
|
|
// Implementation mode:
|
|
@@ -217,20 +221,20 @@
|
|
|
// call this with the mouse x,y on a mouse down; it will update the cursor
|
|
// call this with the mouse x,y on a mouse down; it will update the cursor
|
|
|
// and reset the selection start/end to the cursor point. the x,y must
|
|
// and reset the selection start/end to the cursor point. the x,y must
|
|
|
// be relative to the text widget, with (0,0) being the top left.
|
|
// be relative to the text widget, with (0,0) being the top left.
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
// drag:
|
|
// drag:
|
|
|
// call this with the mouse x,y on a mouse drag/up; it will update the
|
|
// call this with the mouse x,y on a mouse drag/up; it will update the
|
|
|
// cursor and the selection end point
|
|
// cursor and the selection end point
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
// cut:
|
|
// cut:
|
|
|
// call this to delete the current selection; returns true if there was
|
|
// call this to delete the current selection; returns true if there was
|
|
|
// one. you should FIRST copy the current selection to the system paste buffer.
|
|
// one. you should FIRST copy the current selection to the system paste buffer.
|
|
|
// (To copy, just copy the current selection out of the string yourself.)
|
|
// (To copy, just copy the current selection out of the string yourself.)
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
// paste:
|
|
// paste:
|
|
|
// call this to paste text at the current cursor point or over the current
|
|
// call this to paste text at the current cursor point or over the current
|
|
|
// selection if there is one.
|
|
// selection if there is one.
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
// key:
|
|
// key:
|
|
|
// call this for keyboard inputs sent to the textfield. you can use it
|
|
// call this for keyboard inputs sent to the textfield. you can use it
|
|
|
// for "key down" events or for "translated" key events. if you need to
|
|
// for "key down" events or for "translated" key events. if you need to
|
|
@@ -241,7 +245,7 @@
|
|
|
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
|
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
|
|
// anything other type you wante before including.
|
|
// anything other type you wante before including.
|
|
|
//
|
|
//
|
|
|
-//
|
|
|
|
|
|
|
+//
|
|
|
// When rendering, you can read the cursor position and selection state from
|
|
// When rendering, you can read the cursor position and selection state from
|
|
|
// the STB_TexteditState.
|
|
// the STB_TexteditState.
|
|
|
//
|
|
//
|
|
@@ -271,8 +275,8 @@
|
|
|
////
|
|
////
|
|
|
////
|
|
////
|
|
|
|
|
|
|
|
-#ifndef INCLUDE_STB_TEXTEDIT_H
|
|
|
|
|
-#define INCLUDE_STB_TEXTEDIT_H
|
|
|
|
|
|
|
+#ifndef INCLUDE_IMSTB_TEXTEDIT_H
|
|
|
|
|
+#define INCLUDE_IMSTB_TEXTEDIT_H
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
//
|
|
//
|
|
@@ -283,33 +287,33 @@
|
|
|
// and undo state.
|
|
// and undo state.
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
-#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
|
|
|
|
-#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
|
|
|
|
|
|
+#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
|
|
|
|
|
+#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
|
|
#endif
|
|
#endif
|
|
|
-#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
|
|
|
|
-#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
|
|
|
|
|
|
+#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
|
|
|
|
|
+#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
|
|
#endif
|
|
#endif
|
|
|
-#ifndef STB_TEXTEDIT_CHARTYPE
|
|
|
|
|
-#define STB_TEXTEDIT_CHARTYPE int
|
|
|
|
|
|
|
+#ifndef IMSTB_TEXTEDIT_CHARTYPE
|
|
|
|
|
+#define IMSTB_TEXTEDIT_CHARTYPE int
|
|
|
#endif
|
|
#endif
|
|
|
-#ifndef STB_TEXTEDIT_POSITIONTYPE
|
|
|
|
|
-#define STB_TEXTEDIT_POSITIONTYPE int
|
|
|
|
|
|
|
+#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
|
|
|
|
|
+#define IMSTB_TEXTEDIT_POSITIONTYPE int
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct
|
|
typedef struct
|
|
|
{
|
|
{
|
|
|
// private data
|
|
// private data
|
|
|
- STB_TEXTEDIT_POSITIONTYPE where;
|
|
|
|
|
- STB_TEXTEDIT_POSITIONTYPE insert_length;
|
|
|
|
|
- STB_TEXTEDIT_POSITIONTYPE delete_length;
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_POSITIONTYPE where;
|
|
|
|
|
+ IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
|
|
|
|
|
+ IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
|
|
|
int char_storage;
|
|
int char_storage;
|
|
|
} StbUndoRecord;
|
|
} StbUndoRecord;
|
|
|
|
|
|
|
|
typedef struct
|
|
typedef struct
|
|
|
{
|
|
{
|
|
|
// private data
|
|
// private data
|
|
|
- StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
|
|
|
|
- STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
|
|
|
|
|
|
+ StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
|
|
|
|
|
+ IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
|
|
|
short undo_point, redo_point;
|
|
short undo_point, redo_point;
|
|
|
int undo_char_point, redo_char_point;
|
|
int undo_char_point, redo_char_point;
|
|
|
} StbUndoState;
|
|
} StbUndoState;
|
|
@@ -368,7 +372,7 @@ typedef struct
|
|
|
float ymin,ymax; // height of row above and below baseline
|
|
float ymin,ymax; // height of row above and below baseline
|
|
|
int num_chars;
|
|
int num_chars;
|
|
|
} StbTexteditRow;
|
|
} StbTexteditRow;
|
|
|
-#endif //INCLUDE_STB_TEXTEDIT_H
|
|
|
|
|
|
|
+#endif //INCLUDE_IMSTB_TEXTEDIT_H
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////
|
|
@@ -381,11 +385,11 @@ typedef struct
|
|
|
|
|
|
|
|
// implementation isn't include-guarded, since it might have indirectly
|
|
// implementation isn't include-guarded, since it might have indirectly
|
|
|
// included just the "header" portion
|
|
// included just the "header" portion
|
|
|
-#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
|
|
|
|
|
|
+#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
|
|
|
|
|
|
|
|
-#ifndef STB_TEXTEDIT_memmove
|
|
|
|
|
|
|
+#ifndef IMSTB_TEXTEDIT_memmove
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
-#define STB_TEXTEDIT_memmove memmove
|
|
|
|
|
|
|
+#define IMSTB_TEXTEDIT_memmove memmove
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
@@ -395,7 +399,7 @@ typedef struct
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
// traverse the layout to locate the nearest character to a display position
|
|
// traverse the layout to locate the nearest character to a display position
|
|
|
-static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
|
|
|
|
|
|
+static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
|
|
{
|
|
{
|
|
|
StbTexteditRow r;
|
|
StbTexteditRow r;
|
|
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
|
@@ -455,7 +459,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
|
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
|
|
-static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
|
|
|
|
|
|
+static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
|
|
{
|
|
{
|
|
|
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
|
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
|
|
// goes off the top or bottom of the text
|
|
// goes off the top or bottom of the text
|
|
@@ -473,7 +477,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
|
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
|
|
-static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
|
|
|
|
|
|
+static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
|
|
{
|
|
{
|
|
|
int p = 0;
|
|
int p = 0;
|
|
|
|
|
|
|
@@ -499,11 +503,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
|
|
//
|
|
//
|
|
|
|
|
|
|
|
// forward declarations
|
|
// forward declarations
|
|
|
-static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
|
|
|
|
-static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
|
|
|
|
-static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
|
|
|
|
|
|
+static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
|
|
|
|
+static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
|
|
|
|
+static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
|
|
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
|
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
|
|
-static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
|
|
|
|
|
|
+static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
|
|
|
|
|
|
|
typedef struct
|
|
typedef struct
|
|
|
{
|
|
{
|
|
@@ -515,36 +519,21 @@ typedef struct
|
|
|
|
|
|
|
|
// find the x/y location of a character, and remember info about the previous row in
|
|
// find the x/y location of a character, and remember info about the previous row in
|
|
|
// case we get a move-up event (for page up, we'll have to rescan)
|
|
// case we get a move-up event (for page up, we'll have to rescan)
|
|
|
-static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
|
|
|
|
|
|
+static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
|
|
|
{
|
|
{
|
|
|
StbTexteditRow r;
|
|
StbTexteditRow r;
|
|
|
int prev_start = 0;
|
|
int prev_start = 0;
|
|
|
int z = STB_TEXTEDIT_STRINGLEN(str);
|
|
int z = STB_TEXTEDIT_STRINGLEN(str);
|
|
|
int i=0, first;
|
|
int i=0, first;
|
|
|
|
|
|
|
|
- if (n == z) {
|
|
|
|
|
- // if it's at the end, then find the last line -- simpler than trying to
|
|
|
|
|
- // explicitly handle this case in the regular code
|
|
|
|
|
- if (single_line) {
|
|
|
|
|
- STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
|
|
|
|
- find->y = 0;
|
|
|
|
|
- find->first_char = 0;
|
|
|
|
|
- find->length = z;
|
|
|
|
|
- find->height = r.ymax - r.ymin;
|
|
|
|
|
- find->x = r.x1;
|
|
|
|
|
- } else {
|
|
|
|
|
- find->y = 0;
|
|
|
|
|
- find->x = 0;
|
|
|
|
|
- find->height = 1;
|
|
|
|
|
- while (i < z) {
|
|
|
|
|
- STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
|
|
|
|
- prev_start = i;
|
|
|
|
|
- i += r.num_chars;
|
|
|
|
|
- }
|
|
|
|
|
- find->first_char = i;
|
|
|
|
|
- find->length = 0;
|
|
|
|
|
- find->prev_first = prev_start;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (n == z && single_line) {
|
|
|
|
|
+ // special case if it's at the end (may not be needed?)
|
|
|
|
|
+ STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
|
|
|
|
+ find->y = 0;
|
|
|
|
|
+ find->first_char = 0;
|
|
|
|
|
+ find->length = z;
|
|
|
|
|
+ find->height = r.ymax - r.ymin;
|
|
|
|
|
+ find->x = r.x1;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -555,9 +544,16 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
|
|
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
|
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
|
|
if (n < i + r.num_chars)
|
|
if (n < i + r.num_chars)
|
|
|
break;
|
|
break;
|
|
|
|
|
+ if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
|
|
|
|
|
+ break; // [DEAR IMGUI]
|
|
|
prev_start = i;
|
|
prev_start = i;
|
|
|
i += r.num_chars;
|
|
i += r.num_chars;
|
|
|
find->y += r.baseline_y_delta;
|
|
find->y += r.baseline_y_delta;
|
|
|
|
|
+ if (i == z) // [DEAR IMGUI]
|
|
|
|
|
+ {
|
|
|
|
|
+ r.num_chars = 0; // [DEAR IMGUI]
|
|
|
|
|
+ break; // [DEAR IMGUI]
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
find->first_char = first = i;
|
|
find->first_char = first = i;
|
|
@@ -574,7 +570,7 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
|
|
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
|
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
|
|
|
|
|
|
|
// make the selection/cursor state valid if client altered the string
|
|
// make the selection/cursor state valid if client altered the string
|
|
|
-static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
@@ -588,7 +584,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// delete characters while updating undo
|
|
// delete characters while updating undo
|
|
|
-static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
|
|
|
|
|
|
+static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
|
|
{
|
|
{
|
|
|
stb_text_makeundo_delete(str, state, where, len);
|
|
stb_text_makeundo_delete(str, state, where, len);
|
|
|
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
|
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
|
@@ -596,7 +592,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// delete the section
|
|
// delete the section
|
|
|
-static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
stb_textedit_clamp(str, state);
|
|
stb_textedit_clamp(str, state);
|
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
@@ -633,7 +629,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// move cursor to last character of selection
|
|
// move cursor to last character of selection
|
|
|
-static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
|
stb_textedit_sortselection(state);
|
|
stb_textedit_sortselection(state);
|
|
@@ -645,13 +641,13 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef STB_TEXTEDIT_IS_SPACE
|
|
#ifdef STB_TEXTEDIT_IS_SPACE
|
|
|
-static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
|
|
|
|
|
|
+static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
|
|
{
|
|
{
|
|
|
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
|
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
|
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
|
|
-static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
|
|
|
|
|
|
+static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
|
|
{
|
|
{
|
|
|
--c; // always move at least one character
|
|
--c; // always move at least one character
|
|
|
while( c >= 0 && !is_word_boundary( str, c ) )
|
|
while( c >= 0 && !is_word_boundary( str, c ) )
|
|
@@ -666,7 +662,7 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
|
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
|
|
-static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
|
|
|
|
|
|
|
+static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
|
|
{
|
|
{
|
|
|
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
|
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
|
|
++c; // always move at least one character
|
|
++c; // always move at least one character
|
|
@@ -693,7 +689,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// API cut: delete selection
|
|
// API cut: delete selection
|
|
|
-static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
|
|
stb_textedit_delete_selection(str,state); // implicitly clamps
|
|
stb_textedit_delete_selection(str,state); // implicitly clamps
|
|
@@ -704,7 +700,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// API paste: replace existing selection with passed-in text
|
|
// API paste: replace existing selection with passed-in text
|
|
|
-static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
|
|
|
|
|
|
+static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
|
|
|
{
|
|
{
|
|
|
// if there's a selection, the paste should delete it
|
|
// if there's a selection, the paste should delete it
|
|
|
stb_textedit_clamp(str, state);
|
|
stb_textedit_clamp(str, state);
|
|
@@ -716,9 +712,7 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
- // remove the undo since we didn't actually insert the characters
|
|
|
|
|
- if (state->undostate.undo_point)
|
|
|
|
|
- --state->undostate.undo_point;
|
|
|
|
|
|
|
+ // note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -727,14 +721,14 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
// API key: process a keyboard input
|
|
// API key: process a keyboard input
|
|
|
-static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
|
|
|
|
|
|
+static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
|
|
{
|
|
{
|
|
|
retry:
|
|
retry:
|
|
|
switch (key) {
|
|
switch (key) {
|
|
|
default: {
|
|
default: {
|
|
|
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
|
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
|
|
if (c > 0) {
|
|
if (c > 0) {
|
|
|
- STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
|
|
|
|
|
|
|
// can't add newline in single-line mode
|
|
// can't add newline in single-line mode
|
|
|
if (c == '\n' && state->single_line)
|
|
if (c == '\n' && state->single_line)
|
|
@@ -764,7 +758,7 @@ retry:
|
|
|
state->insert_mode = !state->insert_mode;
|
|
state->insert_mode = !state->insert_mode;
|
|
|
break;
|
|
break;
|
|
|
#endif
|
|
#endif
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
case STB_TEXTEDIT_K_UNDO:
|
|
case STB_TEXTEDIT_K_UNDO:
|
|
|
stb_text_undo(str, state);
|
|
stb_text_undo(str, state);
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
@@ -779,7 +773,7 @@ retry:
|
|
|
// if currently there's a selection, move cursor to start of selection
|
|
// if currently there's a selection, move cursor to start of selection
|
|
|
if (STB_TEXT_HAS_SELECTION(state))
|
|
if (STB_TEXT_HAS_SELECTION(state))
|
|
|
stb_textedit_move_to_first(state);
|
|
stb_textedit_move_to_first(state);
|
|
|
- else
|
|
|
|
|
|
|
+ else
|
|
|
if (state->cursor > 0)
|
|
if (state->cursor > 0)
|
|
|
--state->cursor;
|
|
--state->cursor;
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
@@ -828,7 +822,7 @@ retry:
|
|
|
|
|
|
|
|
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
|
|
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
|
|
|
case STB_TEXTEDIT_K_WORDRIGHT:
|
|
case STB_TEXTEDIT_K_WORDRIGHT:
|
|
|
- if (STB_TEXT_HAS_SELECTION(state))
|
|
|
|
|
|
|
+ if (STB_TEXT_HAS_SELECTION(state))
|
|
|
stb_textedit_move_to_last(str, state);
|
|
stb_textedit_move_to_last(str, state);
|
|
|
else {
|
|
else {
|
|
|
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
|
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
|
@@ -899,8 +893,8 @@ retry:
|
|
|
x = row.x0;
|
|
x = row.x0;
|
|
|
for (i=0; i < row.num_chars; ++i) {
|
|
for (i=0; i < row.num_chars; ++i) {
|
|
|
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
|
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
|
|
- #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
|
|
|
|
- if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
|
|
|
|
|
|
+ #ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
|
|
|
|
+ if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
|
|
break;
|
|
break;
|
|
|
#endif
|
|
#endif
|
|
|
x += dx;
|
|
x += dx;
|
|
@@ -922,7 +916,7 @@ retry:
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
case STB_TEXTEDIT_K_UP:
|
|
case STB_TEXTEDIT_K_UP:
|
|
|
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
|
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
|
|
case STB_TEXTEDIT_K_PGUP:
|
|
case STB_TEXTEDIT_K_PGUP:
|
|
@@ -961,8 +955,8 @@ retry:
|
|
|
x = row.x0;
|
|
x = row.x0;
|
|
|
for (i=0; i < row.num_chars; ++i) {
|
|
for (i=0; i < row.num_chars; ++i) {
|
|
|
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
|
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
|
|
- #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
|
|
|
|
- if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
|
|
|
|
|
|
+ #ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
|
|
|
|
+ if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
|
|
break;
|
|
break;
|
|
|
#endif
|
|
#endif
|
|
|
x += dx;
|
|
x += dx;
|
|
@@ -1014,7 +1008,7 @@ retry:
|
|
|
}
|
|
}
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
|
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
|
|
case STB_TEXTEDIT_K_TEXTSTART2:
|
|
case STB_TEXTEDIT_K_TEXTSTART2:
|
|
|
#endif
|
|
#endif
|
|
@@ -1031,7 +1025,7 @@ retry:
|
|
|
state->select_start = state->select_end = 0;
|
|
state->select_start = state->select_end = 0;
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
|
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
|
|
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
|
|
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
|
|
|
#endif
|
|
#endif
|
|
@@ -1119,8 +1113,8 @@ retry:
|
|
|
|
|
|
|
|
static void stb_textedit_flush_redo(StbUndoState *state)
|
|
static void stb_textedit_flush_redo(StbUndoState *state)
|
|
|
{
|
|
{
|
|
|
- state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
|
|
|
|
- state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
|
|
|
|
|
|
+ state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
|
|
|
|
+ state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// discard the oldest entry in the undo list
|
|
// discard the oldest entry in the undo list
|
|
@@ -1132,13 +1126,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
|
|
int n = state->undo_rec[0].insert_length, i;
|
|
int n = state->undo_rec[0].insert_length, i;
|
|
|
// delete n characters from all other records
|
|
// delete n characters from all other records
|
|
|
state->undo_char_point -= n;
|
|
state->undo_char_point -= n;
|
|
|
- STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
|
|
for (i=0; i < state->undo_point; ++i)
|
|
for (i=0; i < state->undo_point; ++i)
|
|
|
if (state->undo_rec[i].char_storage >= 0)
|
|
if (state->undo_rec[i].char_storage >= 0)
|
|
|
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
|
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
|
|
}
|
|
}
|
|
|
--state->undo_point;
|
|
--state->undo_point;
|
|
|
- STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1148,7 +1142,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
|
|
// fill up even though the undo buffer didn't
|
|
// fill up even though the undo buffer didn't
|
|
|
static void stb_textedit_discard_redo(StbUndoState *state)
|
|
static void stb_textedit_discard_redo(StbUndoState *state)
|
|
|
{
|
|
{
|
|
|
- int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
|
|
|
|
|
|
+ int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
|
|
|
|
|
|
|
|
if (state->redo_point <= k) {
|
|
if (state->redo_point <= k) {
|
|
|
// if the k'th undo state has characters, clean those up
|
|
// if the k'th undo state has characters, clean those up
|
|
@@ -1156,7 +1150,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
|
|
int n = state->undo_rec[k].insert_length, i;
|
|
int n = state->undo_rec[k].insert_length, i;
|
|
|
// move the remaining redo character data to the end of the buffer
|
|
// move the remaining redo character data to the end of the buffer
|
|
|
state->redo_char_point += n;
|
|
state->redo_char_point += n;
|
|
|
- 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)));
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
|
|
// adjust the position of all the other records to account for above memmove
|
|
// adjust the position of all the other records to account for above memmove
|
|
|
for (i=state->redo_point; i < k; ++i)
|
|
for (i=state->redo_point; i < k; ++i)
|
|
|
if (state->undo_rec[i].char_storage >= 0)
|
|
if (state->undo_rec[i].char_storage >= 0)
|
|
@@ -1164,12 +1158,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
|
|
}
|
|
}
|
|
|
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
|
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
|
|
// [DEAR IMGUI]
|
|
// [DEAR IMGUI]
|
|
|
- size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
|
|
|
|
|
|
+ size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
|
|
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
|
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
|
|
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
|
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
|
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
|
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
|
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
|
|
- STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
|
|
|
|
|
|
|
// now move redo_point to point to the new one
|
|
// now move redo_point to point to the new one
|
|
|
++state->redo_point;
|
|
++state->redo_point;
|
|
@@ -1183,32 +1177,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
|
|
|
|
|
|
|
|
// if we have no free records, we have to make room, by sliding the
|
|
// if we have no free records, we have to make room, by sliding the
|
|
|
// existing records down
|
|
// existing records down
|
|
|
- if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
|
|
|
|
+ if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
stb_textedit_discard_undo(state);
|
|
stb_textedit_discard_undo(state);
|
|
|
|
|
|
|
|
// if the characters to store won't possibly fit in the buffer, we can't undo
|
|
// if the characters to store won't possibly fit in the buffer, we can't undo
|
|
|
- if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
|
|
|
|
|
|
+ if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
|
|
state->undo_point = 0;
|
|
state->undo_point = 0;
|
|
|
state->undo_char_point = 0;
|
|
state->undo_char_point = 0;
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// if we don't have enough free characters in the buffer, we have to make room
|
|
// if we don't have enough free characters in the buffer, we have to make room
|
|
|
- while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
|
|
|
|
|
|
+ while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
|
|
|
stb_textedit_discard_undo(state);
|
|
stb_textedit_discard_undo(state);
|
|
|
|
|
|
|
|
return &state->undo_rec[state->undo_point++];
|
|
return &state->undo_rec[state->undo_point++];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
|
|
|
|
|
|
+static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
|
|
{
|
|
{
|
|
|
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
|
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
|
|
if (r == NULL)
|
|
if (r == NULL)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
|
|
r->where = pos;
|
|
r->where = pos;
|
|
|
- r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
|
|
|
|
- r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
|
|
|
|
|
|
+ r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
|
|
|
|
|
+ r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
|
|
|
|
|
|
|
|
if (insert_len == 0) {
|
|
if (insert_len == 0) {
|
|
|
r->char_storage = -1;
|
|
r->char_storage = -1;
|
|
@@ -1220,7 +1214,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
StbUndoState *s = &state->undostate;
|
|
StbUndoState *s = &state->undostate;
|
|
|
StbUndoRecord u, *r;
|
|
StbUndoRecord u, *r;
|
|
@@ -1247,7 +1241,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
// characters stored for *undoing* don't leave room for redo
|
|
// characters stored for *undoing* don't leave room for redo
|
|
|
// if the last is true, we have to bail
|
|
// if the last is true, we have to bail
|
|
|
|
|
|
|
|
- if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
|
|
|
|
|
|
+ if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
|
|
// the undo records take up too much character space; there's no space to store the redo characters
|
|
// the undo records take up too much character space; there's no space to store the redo characters
|
|
|
r->insert_length = 0;
|
|
r->insert_length = 0;
|
|
|
} else {
|
|
} else {
|
|
@@ -1256,7 +1250,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
// there's definitely room to store the characters eventually
|
|
// there's definitely room to store the characters eventually
|
|
|
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
|
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
|
|
// should never happen:
|
|
// should never happen:
|
|
|
- if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
|
|
|
|
+ if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
return;
|
|
return;
|
|
|
// there's currently not enough room, so discard a redo record
|
|
// there's currently not enough room, so discard a redo record
|
|
|
stb_textedit_discard_redo(s);
|
|
stb_textedit_discard_redo(s);
|
|
@@ -1288,11 +1282,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
s->redo_point--;
|
|
s->redo_point--;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
|
|
|
|
+static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
|
|
{
|
|
{
|
|
|
StbUndoState *s = &state->undostate;
|
|
StbUndoState *s = &state->undostate;
|
|
|
StbUndoRecord *u, r;
|
|
StbUndoRecord *u, r;
|
|
|
- if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
|
|
|
|
+ if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
// we need to do two things: apply the redo record, and create an undo record
|
|
// we need to do two things: apply the redo record, and create an undo record
|
|
@@ -1344,20 +1338,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
|
|
|
stb_text_createundo(&state->undostate, where, 0, length);
|
|
stb_text_createundo(&state->undostate, where, 0, length);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
|
|
|
|
|
|
+static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
|
|
{
|
|
{
|
|
|
int i;
|
|
int i;
|
|
|
- STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
|
|
if (p) {
|
|
if (p) {
|
|
|
for (i=0; i < length; ++i)
|
|
for (i=0; i < length; ++i)
|
|
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
|
|
|
|
|
|
+static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
|
|
{
|
|
{
|
|
|
int i;
|
|
int i;
|
|
|
- STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
|
|
|
|
|
|
+ IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
|
|
if (p) {
|
|
if (p) {
|
|
|
for (i=0; i < old_length; ++i)
|
|
for (i=0; i < old_length; ++i)
|
|
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
|
@@ -1369,8 +1363,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
|
|
{
|
|
{
|
|
|
state->undostate.undo_point = 0;
|
|
state->undostate.undo_point = 0;
|
|
|
state->undostate.undo_char_point = 0;
|
|
state->undostate.undo_char_point = 0;
|
|
|
- state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
|
|
|
|
- state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
|
|
|
|
|
|
+ state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
|
|
|
|
+ state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
|
|
state->select_end = state->select_start = 0;
|
|
state->select_end = state->select_start = 0;
|
|
|
state->cursor = 0;
|
|
state->cursor = 0;
|
|
|
state->has_preferred_x = 0;
|
|
state->has_preferred_x = 0;
|
|
@@ -1393,16 +1387,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
|
|
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
|
|
|
|
|
|
+static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
|
|
{
|
|
{
|
|
|
- return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
|
|
|
|
|
|
+ return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
|
#pragma GCC diagnostic pop
|
|
#pragma GCC diagnostic pop
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-#endif//STB_TEXTEDIT_IMPLEMENTATION
|
|
|
|
|
|
|
+#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------
|
|
@@ -1410,38 +1404,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
|
|
|
------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------
|
|
|
ALTERNATIVE A - MIT License
|
|
ALTERNATIVE A - MIT License
|
|
|
Copyright (c) 2017 Sean Barrett
|
|
Copyright (c) 2017 Sean Barrett
|
|
|
-Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
|
-this software and associated documentation files (the "Software"), to deal in
|
|
|
|
|
-the Software without restriction, including without limitation the rights to
|
|
|
|
|
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
|
-of the Software, and to permit persons to whom the Software is furnished to do
|
|
|
|
|
|
|
+Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
|
+this software and associated documentation files (the "Software"), to deal in
|
|
|
|
|
+the Software without restriction, including without limitation the rights to
|
|
|
|
|
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
|
+of the Software, and to permit persons to whom the Software is furnished to do
|
|
|
so, subject to the following conditions:
|
|
so, subject to the following conditions:
|
|
|
-The above copyright notice and this permission notice shall be included in all
|
|
|
|
|
|
|
+The above copyright notice and this permission notice shall be included in all
|
|
|
copies or substantial portions of the Software.
|
|
copies or substantial portions of the Software.
|
|
|
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
|
|
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
SOFTWARE.
|
|
SOFTWARE.
|
|
|
------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------
|
|
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
|
|
This is free and unencumbered software released into the public domain.
|
|
This is free and unencumbered software released into the public domain.
|
|
|
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
|
|
|
|
-software, either in source code form or as a compiled binary, for any purpose,
|
|
|
|
|
|
|
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
|
|
|
|
+software, either in source code form or as a compiled binary, for any purpose,
|
|
|
commercial or non-commercial, and by any means.
|
|
commercial or non-commercial, and by any means.
|
|
|
-In jurisdictions that recognize copyright laws, the author or authors of this
|
|
|
|
|
-software dedicate any and all copyright interest in the software to the public
|
|
|
|
|
-domain. We make this dedication for the benefit of the public at large and to
|
|
|
|
|
-the detriment of our heirs and successors. We intend this dedication to be an
|
|
|
|
|
-overt act of relinquishment in perpetuity of all present and future rights to
|
|
|
|
|
|
|
+In jurisdictions that recognize copyright laws, the author or authors of this
|
|
|
|
|
+software dedicate any and all copyright interest in the software to the public
|
|
|
|
|
+domain. We make this dedication for the benefit of the public at large and to
|
|
|
|
|
+the detriment of our heirs and successors. We intend this dedication to be an
|
|
|
|
|
+overt act of relinquishment in perpetuity of all present and future rights to
|
|
|
this software under copyright law.
|
|
this software under copyright law.
|
|
|
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
-AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
|
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
|
|
|
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
|
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------
|
|
|
*/
|
|
*/
|