[escher/ion] Factorize code for removing a code point in text field/area

This commit is contained in:
Léa Saviot
2019-01-24 11:34:50 +01:00
committed by Émilie Feral
parent 9e06b23bbb
commit f9fbcabb30
5 changed files with 46 additions and 38 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}
};