mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-15 18:57:08 +00:00
Formspec: Implement Ctrl+Shift+Left/Right text selection (#16455)
This is a quality-of-life improvement to edit text more easily.
This commit is contained in:
parent
024e1d2d27
commit
d24a7001ab
2 changed files with 58 additions and 30 deletions
|
@ -279,6 +279,11 @@ bool GUIEditBox::processKey(const SEvent &event)
|
||||||
new_mark_end = 0;
|
new_mark_end = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KEY_LEFT:
|
||||||
|
case KEY_RIGHT:
|
||||||
|
processKeyLR(event.KeyInput, new_mark_begin, new_mark_end);
|
||||||
|
m_blink_start_time = porting::getTimeMs();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -335,37 +340,8 @@ bool GUIEditBox::processKey(const SEvent &event)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case KEY_LEFT:
|
case KEY_LEFT:
|
||||||
if (event.KeyInput.Shift) {
|
|
||||||
if (m_cursor_pos > 0) {
|
|
||||||
if (m_mark_begin == m_mark_end)
|
|
||||||
new_mark_begin = m_cursor_pos;
|
|
||||||
|
|
||||||
new_mark_end = m_cursor_pos - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
new_mark_begin = 0;
|
|
||||||
new_mark_end = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_cursor_pos > 0)
|
|
||||||
m_cursor_pos--;
|
|
||||||
m_blink_start_time = porting::getTimeMs();
|
|
||||||
break;
|
|
||||||
case KEY_RIGHT:
|
case KEY_RIGHT:
|
||||||
if (event.KeyInput.Shift) {
|
processKeyLR(event.KeyInput, new_mark_begin, new_mark_end);
|
||||||
if (Text.size() > (u32)m_cursor_pos) {
|
|
||||||
if (m_mark_begin == m_mark_end)
|
|
||||||
new_mark_begin = m_cursor_pos;
|
|
||||||
|
|
||||||
new_mark_end = m_cursor_pos + 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
new_mark_begin = 0;
|
|
||||||
new_mark_end = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Text.size() > (u32)m_cursor_pos)
|
|
||||||
m_cursor_pos++;
|
|
||||||
m_blink_start_time = porting::getTimeMs();
|
m_blink_start_time = porting::getTimeMs();
|
||||||
break;
|
break;
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
|
@ -436,6 +412,54 @@ bool GUIEditBox::processKey(const SEvent &event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIEditBox::processKeyLR(const SEvent::SKeyInput &input, s32 &new_mark_begin,
|
||||||
|
s32 &new_mark_end)
|
||||||
|
{
|
||||||
|
const s8 dir = input.Key == KEY_RIGHT ? 1 : -1;
|
||||||
|
|
||||||
|
s32 new_pos = m_cursor_pos;
|
||||||
|
if (input.Control) {
|
||||||
|
// Advance to next/previous word
|
||||||
|
wchar_t prev_c = L'\0';
|
||||||
|
for (s32 i = new_pos; i >= 0 && i <= (s32)Text.size(); i += dir) {
|
||||||
|
// This only handles Latin characters.
|
||||||
|
const wchar_t c = Text[i];
|
||||||
|
|
||||||
|
new_pos = i;
|
||||||
|
if (std::abs(i - m_cursor_pos) > 2) {
|
||||||
|
// End of word
|
||||||
|
if (!std::iswspace(prev_c) && std::iswspace(c))
|
||||||
|
break;
|
||||||
|
// End of a sentence.
|
||||||
|
if (std::iswpunct(prev_c) && !std::iswpunct(c))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_c = c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Advance by +1/-1 character
|
||||||
|
new_pos += dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.Shift) {
|
||||||
|
// Reset selection
|
||||||
|
new_mark_begin = 0;
|
||||||
|
new_mark_end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_pos >= 0 && new_pos <= (s32)Text.size()) {
|
||||||
|
// Update cursor (and selection)
|
||||||
|
if (input.Shift) {
|
||||||
|
if (m_mark_begin == m_mark_end)
|
||||||
|
new_mark_begin = m_cursor_pos;
|
||||||
|
|
||||||
|
new_mark_end = new_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cursor_pos = new_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GUIEditBox::onKeyUp(const SEvent &event, s32 &mark_begin, s32 &mark_end)
|
bool GUIEditBox::onKeyUp(const SEvent &event, s32 &mark_begin, s32 &mark_end)
|
||||||
{
|
{
|
||||||
if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) {
|
if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) {
|
||||||
|
|
|
@ -135,6 +135,10 @@ protected:
|
||||||
virtual s32 getCursorPos(s32 x, s32 y) = 0;
|
virtual s32 getCursorPos(s32 x, s32 y) = 0;
|
||||||
|
|
||||||
bool processKey(const SEvent &event);
|
bool processKey(const SEvent &event);
|
||||||
|
//! KEY_LEFT / KEY_RIGHT inputs
|
||||||
|
void processKeyLR(const SEvent::SKeyInput &input, s32 &new_mark_begin,
|
||||||
|
s32 &new_mark_end);
|
||||||
|
|
||||||
virtual void inputString(const core::stringw &str);
|
virtual void inputString(const core::stringw &str);
|
||||||
virtual void inputChar(wchar_t c);
|
virtual void inputChar(wchar_t c);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue