textbox bugfix; more assertions in textbox on caret position

This commit is contained in:
nakst 2022-01-04 21:45:26 +00:00
parent 082053d507
commit ac4fce50ce
3 changed files with 29 additions and 4 deletions

View File

@ -50,6 +50,7 @@ struct EsTextbox : EsElement {
TextboxCaret carets[2]; // carets[1] is the actual caret; carets[0] is the selection anchor. TextboxCaret carets[2]; // carets[1] is the actual caret; carets[0] is the selection anchor.
TextboxCaret wordSelectionAnchor, wordSelectionAnchor2; TextboxCaret wordSelectionAnchor, wordSelectionAnchor2;
bool wordSelectionAnchorValid;
Array<DocumentLine> lines; Array<DocumentLine> lines;
Array<TextboxVisibleLine> visibleLines; Array<TextboxVisibleLine> visibleLines;
@ -759,6 +760,11 @@ void EsTextboxMoveCaret(EsTextbox *textbox, int32_t line, int32_t byte) {
textbox->carets[1].byte = byte; textbox->carets[1].byte = byte;
textbox->Repaint(true); textbox->Repaint(true);
TextboxUpdateCommands(textbox, true); TextboxUpdateCommands(textbox, true);
EsAssert(textbox->carets[0].line >= 0 && textbox->carets[0].line < (int32_t) textbox->lines.Length()
&& textbox->carets[0].byte >= 0 && textbox->carets[0].byte <= textbox->lines[textbox->carets[0].line].lengthBytes);
EsAssert(textbox->carets[1].line >= 0 && textbox->carets[1].line < (int32_t) textbox->lines.Length()
&& textbox->carets[1].byte >= 0 && textbox->carets[1].byte <= textbox->lines[textbox->carets[1].line].lengthBytes);
} }
void EsTextboxGetSelection(EsTextbox *textbox, int32_t *fromLine, int32_t *fromByte, int32_t *toLine, int32_t *toByte) { void EsTextboxGetSelection(EsTextbox *textbox, int32_t *fromLine, int32_t *fromByte, int32_t *toLine, int32_t *toByte) {
@ -783,6 +789,11 @@ void EsTextboxSetSelection(EsTextbox *textbox, int32_t fromLine, int32_t fromByt
textbox->Repaint(true); textbox->Repaint(true);
TextboxUpdateCommands(textbox, true); TextboxUpdateCommands(textbox, true);
EsTextboxEnsureCaretVisible(textbox); EsTextboxEnsureCaretVisible(textbox);
EsAssert(textbox->carets[0].line >= 0 && textbox->carets[0].line < (int32_t) textbox->lines.Length()
&& textbox->carets[0].byte >= 0 && textbox->carets[0].byte <= textbox->lines[textbox->carets[0].line].lengthBytes);
EsAssert(textbox->carets[1].line >= 0 && textbox->carets[1].line < (int32_t) textbox->lines.Length()
&& textbox->carets[1].byte >= 0 && textbox->carets[1].byte <= textbox->lines[textbox->carets[1].line].lengthBytes);
} }
void EsTextboxSelectAll(EsTextbox *textbox) { void EsTextboxSelectAll(EsTextbox *textbox) {
@ -860,8 +871,7 @@ void EsTextboxInsert(EsTextbox *textbox, const char *string, ptrdiff_t stringByt
TextboxUndoItemHeader *undoItem = nullptr; TextboxUndoItemHeader *undoItem = nullptr;
size_t undoItemBytes = 0; size_t undoItemBytes = 0;
textbox->wordSelectionAnchor = textbox->carets[0]; textbox->wordSelectionAnchorValid = false;
textbox->wordSelectionAnchor2 = textbox->carets[1];
textbox->verticalMotionHorizontalDepth = -1; textbox->verticalMotionHorizontalDepth = -1;
@ -1179,6 +1189,11 @@ void EsTextboxInsert(EsTextbox *textbox, const char *string, ptrdiff_t stringByt
textbox->scroll.Refresh(); textbox->scroll.Refresh();
TextboxUpdateCommands(textbox, true); TextboxUpdateCommands(textbox, true);
EsAssert(textbox->carets[0].line >= 0 && textbox->carets[0].line < (int32_t) textbox->lines.Length()
&& textbox->carets[0].byte >= 0 && textbox->carets[0].byte <= textbox->lines[textbox->carets[0].line].lengthBytes);
EsAssert(textbox->carets[1].line >= 0 && textbox->carets[1].line < (int32_t) textbox->lines.Length()
&& textbox->carets[1].byte >= 0 && textbox->carets[1].byte <= textbox->lines[textbox->carets[1].line].lengthBytes);
} }
char *EsTextboxGetContents(EsTextbox *textbox, size_t *_bytes, uint32_t flags) { char *EsTextboxGetContents(EsTextbox *textbox, size_t *_bytes, uint32_t flags) {
@ -1381,6 +1396,7 @@ bool TextboxFindCaret(EsTextbox *textbox, int positionX, int positionY, bool sec
ptrdiff_t result = TextGetCharacterAtPoint(textbox, &textbox->textStyle, ptrdiff_t result = TextGetCharacterAtPoint(textbox, &textbox->textStyle,
GET_BUFFER(line), line->lengthBytes, GET_BUFFER(line), line->lengthBytes,
&pointX, ES_TEXT_GET_CHARACTER_AT_POINT_MIDDLE); &pointX, ES_TEXT_GET_CHARACTER_AT_POINT_MIDDLE);
EsAssert(result >= -1 && result <= line->lengthBytes);
textbox->carets[1].byte = result == -1 ? line->lengthBytes : result; textbox->carets[1].byte = result == -1 ? line->lengthBytes : result;
} }
@ -1397,13 +1413,15 @@ bool TextboxFindCaret(EsTextbox *textbox, int positionX, int positionY, bool sec
TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_FORWARDS, MOVE_CARET_WORD, true); TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_FORWARDS, MOVE_CARET_WORD, true);
textbox->wordSelectionAnchor = textbox->carets[0]; textbox->wordSelectionAnchor = textbox->carets[0];
textbox->wordSelectionAnchor2 = textbox->carets[1]; textbox->wordSelectionAnchor2 = textbox->carets[1];
textbox->wordSelectionAnchorValid = true;
} else if (clickChainCount == 3) { } else if (clickChainCount == 3) {
TextboxMoveCaret(textbox, textbox->carets + 0, MOVE_CARET_BACKWARDS, MOVE_CARET_LINE, true); TextboxMoveCaret(textbox, textbox->carets + 0, MOVE_CARET_BACKWARDS, MOVE_CARET_LINE, true);
TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_FORWARDS, MOVE_CARET_LINE, true); TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_FORWARDS, MOVE_CARET_LINE, true);
textbox->wordSelectionAnchor = textbox->carets[0]; textbox->wordSelectionAnchor = textbox->carets[0];
textbox->wordSelectionAnchor2 = textbox->carets[1]; textbox->wordSelectionAnchor2 = textbox->carets[1];
textbox->wordSelectionAnchorValid = true;
} }
} else { } else if (textbox->wordSelectionAnchorValid) {
if (clickChainCount == 2) { if (clickChainCount == 2) {
if (TextboxCompareCarets(textbox->carets + 1, textbox->carets + 0) < 0) { if (TextboxCompareCarets(textbox->carets + 1, textbox->carets + 0) < 0) {
TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_BACKWARDS, MOVE_CARET_WORD); TextboxMoveCaret(textbox, textbox->carets + 1, MOVE_CARET_BACKWARDS, MOVE_CARET_WORD);
@ -1424,6 +1442,11 @@ bool TextboxFindCaret(EsTextbox *textbox, int positionX, int positionY, bool sec
} }
} }
EsAssert(textbox->carets[0].line >= 0 && textbox->carets[0].line < (int32_t) textbox->lines.Length()
&& textbox->carets[0].byte >= 0 && textbox->carets[0].byte <= textbox->lines[textbox->carets[0].line].lengthBytes);
EsAssert(textbox->carets[1].line >= 0 && textbox->carets[1].line < (int32_t) textbox->lines.Length()
&& textbox->carets[1].byte >= 0 && textbox->carets[1].byte <= textbox->lines[textbox->carets[1].line].lengthBytes);
TextboxUpdateCommands(textbox, true); TextboxUpdateCommands(textbox, true);
return textbox->carets[0].line != startLine0 || textbox->carets[1].line != startLine1; return textbox->carets[0].line != startLine0 || textbox->carets[1].line != startLine1;
} }

View File

@ -4,4 +4,4 @@ mkdir -p bin/include_x11
cp root/Applications/POSIX/include/essence.h bin/include_x11 cp root/Applications/POSIX/include/essence.h bin/include_x11
cp root/Essence/Desktop.esx bin/bundle.dat cp root/Essence/Desktop.esx bin/bundle.dat
ld -r -b binary -o bin/Object\ Files/bundle.o bin/bundle.dat ld -r -b binary -o bin/Object\ Files/bundle.o bin/bundle.dat
g++ -o bin/hello_x11 util/x11/platform.cpp apps/text_editor.cpp bin/Object\ Files/bundle.o -lfreetype -lharfbuzz -lX11 -pthread -g -fno-exceptions -Ibin/include_x11 -I. -I/usr/include/freetype2 -DNO_API_TABLE -DUSE_PLATFORM_HEAP -DUSE_FREETYPE_AND_HARFBUZZ -DUSE_STB_SPRINTF -D_start=_StartApplication -D_init=EsHeapValidate -DES_FORWARD -Wall -Wextra -Wno-empty-body -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fsanitize=address g++ -o bin/hello_x11 util/x11/platform.cpp $1 bin/Object\ Files/bundle.o -lfreetype -lharfbuzz -lX11 -pthread -g -fno-exceptions -Ibin/include_x11 -I. -I/usr/include/freetype2 -DNO_API_TABLE -DUSE_PLATFORM_HEAP -DUSE_FREETYPE_AND_HARFBUZZ -DUSE_STB_SPRINTF -D_start=_StartApplication -D_init=EsHeapValidate -DES_FORWARD -Wall -Wextra -Wno-empty-body -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -fsanitize=address

View File

@ -499,6 +499,8 @@ uintptr_t _APISyscall(uintptr_t index, uintptr_t argument0, uintptr_t argument1,
pthread_mutex_unlock(&windowsMutex); pthread_mutex_unlock(&windowsMutex);
return ES_SUCCESS; return ES_SUCCESS;
} else if (index == ES_SYSCALL_PROCESS_CRASH) {
assert(false);
} else { } else {
fprintf(stderr, "Unimplemented system call '%s' (%ld).\n", EnumLookupNameFromValue(enumStrings_EsSyscallType, index), index); fprintf(stderr, "Unimplemented system call '%s' (%ld).\n", EnumLookupNameFromValue(enumStrings_EsSyscallType, index), index);
exit(1); exit(1);