mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[escher/ion] Factorize code for removing a code point in text field/area
This commit is contained in:
@@ -75,7 +75,7 @@ protected:
|
||||
void insertText(const char * s, int textLength, char * location);
|
||||
void insertSpacesAtLocation(int numberOfSpaces, char * location);
|
||||
|
||||
CodePoint removeCodePoint(const char * * position);
|
||||
CodePoint removeCodePoint(char * * position);
|
||||
size_t removeRemainingLine(const char * position, int direction);
|
||||
char operator[](size_t index) {
|
||||
assert(index < m_bufferSize);
|
||||
|
||||
@@ -199,29 +199,17 @@ void TextArea::Text::insertSpacesAtLocation(int numberOfSpaces, char * location)
|
||||
}
|
||||
}
|
||||
|
||||
CodePoint TextArea::Text::removeCodePoint(const char * * position) {
|
||||
CodePoint TextArea::Text::removeCodePoint(char * * position) {
|
||||
assert(m_buffer != nullptr);
|
||||
assert(m_buffer <= *position && *position < m_buffer + m_bufferSize);
|
||||
|
||||
// Find the beginning of the previous code point
|
||||
UTF8Decoder decoder(m_buffer, *position);
|
||||
CodePoint deletedCodePoint = decoder.previousCodePoint();
|
||||
const char * newCursorLocation = decoder.stringPosition();
|
||||
assert(newCursorLocation < *position);
|
||||
CodePoint removedCodePoint = 0;
|
||||
int removedSize = UTF8Helper::RemovePreviousCodePoint(m_buffer, *position, &removedCodePoint);
|
||||
assert(removedSize > 0);
|
||||
|
||||
// Shift the buffer
|
||||
int codePointSize = *position - newCursorLocation;
|
||||
assert(codePointSize == UTF8Decoder::CharSizeOfCodePoint(deletedCodePoint));
|
||||
assert(newCursorLocation >= m_buffer);
|
||||
for (size_t i = newCursorLocation - m_buffer; i < m_bufferSize; i++) {
|
||||
m_buffer[i] = m_buffer[i + codePointSize];
|
||||
if (m_buffer[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Set the new cursor position
|
||||
*position = newCursorLocation;
|
||||
return deletedCodePoint;
|
||||
*position = *position - removedSize;
|
||||
return removedCodePoint;
|
||||
}
|
||||
|
||||
size_t TextArea::Text::removeRemainingLine(const char * location, int direction) {
|
||||
@@ -401,7 +389,7 @@ bool TextArea::TextArea::ContentView::removeCodePoint() {
|
||||
return false;
|
||||
}
|
||||
bool lineBreak = false;
|
||||
const char * cursorLoc = cursorLocation();
|
||||
char * cursorLoc = const_cast<char *>(cursorLocation());
|
||||
lineBreak = m_text.removeCodePoint(&cursorLoc) == '\n';
|
||||
setCursorLocation(cursorLoc); // Update the cursor
|
||||
layoutSubviews(); // Reposition the cursor
|
||||
|
||||
@@ -143,35 +143,28 @@ KDSize TextField::ContentView::minimalSizeForOptimalDisplay() const {
|
||||
|
||||
bool TextField::ContentView::removeCodePoint() {
|
||||
assert(m_isEditing);
|
||||
if (cursorLocation() <= m_draftTextBuffer) {
|
||||
|
||||
// Remove the code point if possible
|
||||
CodePoint removedCodePoint = 0;
|
||||
int removedSize = UTF8Helper::RemovePreviousCodePoint(m_draftTextBuffer, const_cast<char *>(cursorLocation()), &removedCodePoint);
|
||||
if (removedSize == 0) {
|
||||
assert(cursorLocation() == m_draftTextBuffer);
|
||||
return false;
|
||||
}
|
||||
UTF8Decoder decoder(m_draftTextBuffer, cursorLocation());
|
||||
decoder.previousCodePoint();
|
||||
const char * newCursorLocation = decoder.stringPosition();
|
||||
|
||||
assert(newCursorLocation < cursorLocation());
|
||||
int removedCodePointLength = cursorLocation() - newCursorLocation;
|
||||
m_currentDraftTextLength-= removedCodePointLength;
|
||||
// Update the draft buffer length
|
||||
m_currentDraftTextLength-= removedSize;
|
||||
assert(m_draftTextBuffer[m_currentDraftTextLength] == 0);
|
||||
|
||||
// Reload the view and set the cursor location
|
||||
if (m_horizontalAlignment > 0.0f) {
|
||||
reloadRectFromPosition(m_draftTextBuffer);
|
||||
}
|
||||
|
||||
setCursorLocation(newCursorLocation);
|
||||
assert(cursorLocation() - removedSize >= m_draftTextBuffer);
|
||||
setCursorLocation(cursorLocation() - removedSize);
|
||||
if (m_horizontalAlignment == 0.0f) {
|
||||
reloadRectFromPosition(cursorLocation());
|
||||
}
|
||||
|
||||
for (char * k = const_cast<char *>(cursorLocation()); k < m_draftTextBuffer + m_currentDraftTextLength + removedCodePointLength; k++) {
|
||||
*k = *(k+removedCodePointLength);
|
||||
if (*k == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(m_draftTextBuffer[m_currentDraftTextLength] == 0);
|
||||
layoutSubviews();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ const char * PerformAtCodePoints(const char * string, CodePoint c, CodePointAct
|
||||
bool PreviousCodePointIs(const char * buffer, const char * location, CodePoint c);
|
||||
bool CodePointIs(const char * location, CodePoint c);
|
||||
|
||||
// Shift the buffer and return the number of bytes removed.
|
||||
int RemovePreviousCodePoint(const char * text, char * location, CodePoint * c);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -169,4 +169,27 @@ bool CodePointIs(const char * location, CodePoint c) {
|
||||
return decoder.nextCodePoint() == c;
|
||||
}
|
||||
|
||||
int RemovePreviousCodePoint(const char * text, char * location, CodePoint * c) {
|
||||
assert(c != nullptr);
|
||||
if (location <= text) {
|
||||
assert(location == text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find the previous code point
|
||||
UTF8Decoder decoder(text, location);
|
||||
*c = decoder.previousCodePoint();
|
||||
|
||||
// Shift the buffer
|
||||
int codePointSize = UTF8Decoder::CharSizeOfCodePoint(*c);
|
||||
char * iterator = location - codePointSize;
|
||||
assert(iterator >= text);
|
||||
do {
|
||||
*iterator = *(iterator + codePointSize);
|
||||
iterator++;
|
||||
} while (*(iterator - 1) != 0); // Stop shifting after writing a null terminating char.
|
||||
|
||||
return codePointSize;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user