1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 19:13:07 +01:00

Implement #19468 and rename functions cursor to caret

This commit is contained in:
ζeh Matt
2023-02-24 01:11:13 +02:00
parent dc97eb5bbd
commit 365fcf24c3
3 changed files with 185 additions and 48 deletions

View File

@@ -118,14 +118,6 @@ void TextComposition::HandleMessage(const SDL_Event* e)
break;
}
// Clear the input on <CTRL>Backspace (Windows/Linux) or <MOD>Backspace (macOS)
if (key == SDLK_BACKSPACE && (modifier & KEYBOARD_PRIMARY_MODIFIER))
{
Clear();
console.RefreshCaret(_session.SelectionStart);
WindowUpdateTextbox();
}
switch (key)
{
case SDLK_BACKSPACE:
@@ -133,7 +125,10 @@ void TextComposition::HandleMessage(const SDL_Event* e)
if (_session.SelectionStart > 0)
{
size_t endOffset = _session.SelectionStart;
CursorLeft();
if (modifier & KEYBOARD_PRIMARY_MODIFIER)
CaretMoveToLeftToken();
else
CaretMoveLeft();
_session.SelectionSize = endOffset - _session.SelectionStart;
Delete();
@@ -142,17 +137,20 @@ void TextComposition::HandleMessage(const SDL_Event* e)
}
break;
case SDLK_HOME:
CursorHome();
CaretMoveToStart();
console.RefreshCaret(_session.SelectionStart);
break;
case SDLK_END:
CursorEnd();
CaretMoveToEnd();
console.RefreshCaret(_session.SelectionStart);
break;
case SDLK_DELETE:
{
size_t startOffset = _session.SelectionStart;
CursorRight();
if (modifier & KEYBOARD_PRIMARY_MODIFIER)
CaretMoveToRightToken();
else
CaretMoveRight();
_session.SelectionSize = _session.SelectionStart - startOffset;
_session.SelectionStart = startOffset;
Delete();
@@ -164,11 +162,17 @@ void TextComposition::HandleMessage(const SDL_Event* e)
WindowCancelTextbox();
break;
case SDLK_LEFT:
CursorLeft();
if (modifier & KEYBOARD_PRIMARY_MODIFIER)
CaretMoveToLeftToken();
else
CaretMoveLeft();
console.RefreshCaret(_session.SelectionStart);
break;
case SDLK_RIGHT:
CursorRight();
if (modifier & KEYBOARD_PRIMARY_MODIFIER)
CaretMoveToRightToken();
else
CaretMoveRight();
console.RefreshCaret(_session.SelectionStart);
break;
case SDLK_c:
@@ -192,12 +196,12 @@ void TextComposition::HandleMessage(const SDL_Event* e)
}
}
void TextComposition::CursorHome()
void TextComposition::CaretMoveToStart()
{
_session.SelectionStart = 0;
}
void TextComposition::CursorEnd()
void TextComposition::CaretMoveToEnd()
{
size_t selectionOffset = _session.Buffer->size();
const utf8* ch = _session.Buffer->c_str() + _session.SelectionStart;
@@ -210,38 +214,166 @@ void TextComposition::CursorEnd()
_session.SelectionStart = selectionOffset;
}
void TextComposition::CursorLeft()
void TextComposition::CaretMoveLeft()
{
size_t selectionOffset = _session.SelectionStart;
if (selectionOffset > 0)
{
const utf8* ch = _session.Buffer->c_str() + selectionOffset;
do
{
ch--;
selectionOffset--;
} while (!UTF8IsCodepointStart(ch) && selectionOffset > 0);
if (selectionOffset == 0)
return;
_session.SelectionStart = selectionOffset;
}
const utf8* ch = _session.Buffer->c_str() + selectionOffset;
do
{
ch--;
selectionOffset--;
} while (!UTF8IsCodepointStart(ch) && selectionOffset > 0);
_session.SelectionStart = selectionOffset;
}
void TextComposition::CursorRight()
void TextComposition::CaretMoveRight()
{
size_t selectionOffset = _session.SelectionStart;
size_t selectionMaxOffset = _session.Buffer->size();
if (selectionOffset < selectionMaxOffset)
{
const utf8* ch = _session.Buffer->c_str() + _session.SelectionStart;
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
if (selectionOffset >= selectionMaxOffset)
return;
_session.SelectionSize = std::max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
_session.SelectionStart = selectionOffset;
const utf8* ch = _session.Buffer->c_str() + _session.SelectionStart;
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
_session.SelectionSize = std::max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
_session.SelectionStart = selectionOffset;
}
static bool isWhitespace(uint32_t cp)
{
return cp == ' ' || cp == '\t';
}
void TextComposition::CaretMoveToLeftToken()
{
if (_session.SelectionStart == 0)
return;
size_t selectionOffset = _session.SelectionStart - 1;
size_t lastChar = selectionOffset;
const utf8* ch = _session.Buffer->c_str() + selectionOffset;
// Read until first non-whitespace.
while (selectionOffset > 0)
{
while (!UTF8IsCodepointStart(ch) && selectionOffset > 0)
{
ch--;
selectionOffset--;
}
auto cp = UTF8GetNext(ch, nullptr);
if (!isWhitespace(cp))
{
lastChar = selectionOffset;
break;
}
ch--;
selectionOffset--;
}
// Skip white spaces.
while (selectionOffset > 0)
{
while (!UTF8IsCodepointStart(ch) && selectionOffset > 0)
{
ch--;
selectionOffset--;
}
auto cp = UTF8GetNext(ch, nullptr);
if (isWhitespace(cp))
break;
lastChar = selectionOffset;
ch--;
selectionOffset--;
}
_session.SelectionSize = std::max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
_session.SelectionStart = selectionOffset == 0 ? 0 : lastChar;
}
void TextComposition::CaretMoveToRightToken()
{
size_t selectionOffset = _session.SelectionStart;
size_t selectionMaxOffset = _session.Buffer->size();
if (selectionOffset >= selectionMaxOffset)
return;
const utf8* ch = _session.Buffer->c_str() + selectionOffset;
// Find a valid codepoint start.
while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset)
{
ch++;
selectionOffset++;
}
auto cp = UTF8GetNext(ch, nullptr);
if (isWhitespace(cp))
{
// Read until first non-whitespace.
while (selectionOffset < selectionMaxOffset)
{
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
cp = UTF8GetNext(ch, nullptr);
if (!isWhitespace(cp))
break;
}
}
else
{
// Read until first non-whitespace.
while (selectionOffset < selectionMaxOffset)
{
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
cp = UTF8GetNext(ch, nullptr);
if (isWhitespace(cp))
break;
}
// Skip white spaces.
while (selectionOffset < selectionMaxOffset)
{
// Read until first non-whitespace.
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
cp = UTF8GetNext(ch, nullptr);
if (!isWhitespace(cp))
break;
}
}
_session.SelectionSize = std::max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
_session.SelectionStart = selectionOffset;
}
void TextComposition::Insert(const utf8* text)
@@ -292,17 +424,20 @@ void TextComposition::Clear()
void TextComposition::Delete()
{
size_t selectionOffset = _session.SelectionStart;
size_t selectionMaxOffset = _session.Buffer->size();
size_t selectionMaxOffset = std::min(_session.SelectionStart + _session.SelectionSize, _session.Buffer->size());
if (selectionOffset >= selectionMaxOffset)
return;
// Find out how many bytes to delete.
const utf8* ch = _session.Buffer->c_str() + _session.SelectionStart;
do
while (selectionOffset < selectionMaxOffset)
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
do
{
ch++;
selectionOffset++;
} while (!UTF8IsCodepointStart(ch) && selectionOffset < selectionMaxOffset);
}
size_t bytesToSkip = selectionOffset - _session.SelectionStart;
if (bytesToSkip == 0)

View File

@@ -37,10 +37,12 @@ namespace OpenRCT2::Ui
void HandleMessage(const SDL_Event* e);
private:
void CursorHome();
void CursorEnd();
void CursorLeft();
void CursorRight();
void CaretMoveToStart();
void CaretMoveToEnd();
void CaretMoveLeft();
void CaretMoveRight();
void CaretMoveToLeftToken();
void CaretMoveToRightToken();
void Insert(const utf8* text);
void InsertCodepoint(codepoint_t codepoint);
void Clear();

View File

@@ -163,7 +163,7 @@ void ChatDraw(DrawPixelInfo* dpi, uint8_t chatBackgroundColor)
{
if (i >= _chatHistory.size())
break;
uint32_t expireTime = ChatHistoryGetTime(i) + 10000;
if (!gChatOpen && Platform::GetTicks() > expireTime)
{