Fixed TextInput left/right insert/delete functionality for UTF8 and multi-width characters.

This commit is contained in:
Casey Langen 2016-07-07 00:49:50 -07:00
parent f44c3c08c0
commit ec32b70e15
3 changed files with 16 additions and 8 deletions

View File

@ -87,6 +87,10 @@ inline static size_t u8len(const std::string& str) {
/* get the (raw) character index of the "nth" logical/display character */
inline static size_t u8offset(const std::string& str, int n) {
if (str.size() == 0) {
return std::string::npos;
}
std::string::const_iterator it = str.begin();
int count = 0;
@ -95,7 +99,7 @@ inline static size_t u8offset(const std::string& str, int n) {
++count;
}
return (size_t) count;
return (size_t) (it - str.begin());
}
inline static std::string u8substr(const std::string& in, int offset, int len) {

View File

@ -65,7 +65,7 @@ inline static bool removeUtf8Char(std::string& value, size_t position) {
}
else {
size_t offset = u8offset(value, position - 1);
if (offset >= 0) {
if (offset != std::string::npos) {
size_t end = u8offset(value, position);
value.erase(offset, end - offset);
return true;
@ -94,7 +94,9 @@ size_t TextInput::Length() {
}
size_t TextInput::Position() {
return this->position;
/* note we return the COLUMN offset, not the physical or logical
character offset! */
return u8cols(u8substr(this->buffer, 0, this->position));
}
bool TextInput::Write(const std::string& key) {
@ -116,7 +118,9 @@ bool TextInput::Write(const std::string& key) {
/* one character at a time. if it's more than one character, we're
dealing with an escape sequence and should not print it. */
if (u8len(key) == 1) {
this->buffer.insert(u8offset(this->buffer, this->position), key);
size_t offset = u8offset(this->buffer, this->position);
offset = (offset == std::string::npos) ? 0 : offset;
this->buffer.insert(offset, key);
this->TextChanged(this, this->buffer);
++this->position;
}
@ -132,10 +136,10 @@ bool TextInput::Write(const std::string& key) {
bool TextInput::KeyPress(const std::string& key) {
if (key == "KEY_LEFT") {
return this->MoveCursor(-1);
return this->OffsetPosition(-1);
}
else if (key == "KEY_RIGHT") {
return this->MoveCursor(1);
return this->OffsetPosition(1);
}
else if (key == "KEY_HOME") {
this->position = 0;
@ -159,7 +163,7 @@ bool TextInput::KeyPress(const std::string& key) {
return false;
}
bool TextInput::MoveCursor(int delta) {
bool TextInput::OffsetPosition(int delta) {
int actual = this->position + delta;
actual = std::max(0, std::min((int) this->bufferLength, actual));

View File

@ -67,7 +67,7 @@ namespace cursespp {
virtual std::string GetText() { return this->buffer; }
private:
bool MoveCursor(int delta);
bool OffsetPosition(int delta);
std::string buffer;
int position;