mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-18 18:55:29 +02:00
IrrlichtMt: Implement double- and triple-click text selection (#16559)
This commit is contained in:
@@ -185,6 +185,7 @@ protected:
|
||||
bool Border;
|
||||
bool Background;
|
||||
bool OverrideColorEnabled;
|
||||
bool InhibitLeftMouseUpOnce = false;
|
||||
s32 MarkBegin;
|
||||
s32 MarkEnd;
|
||||
|
||||
@@ -196,6 +197,7 @@ protected:
|
||||
u32 BlinkStartTime;
|
||||
u32 CursorBlinkTime;
|
||||
core::stringw CursorChar; // IGUIFont::draw needs stringw instead of wchar_t
|
||||
//! Text insertion position. Is `Text.size()` when appending (rightmost position).
|
||||
s32 CursorPos;
|
||||
s32 HScrollPos, VScrollPos; // scroll position in characters
|
||||
u32 Max;
|
||||
|
@@ -12,13 +12,10 @@
|
||||
#include "rect.h"
|
||||
#include "os.h"
|
||||
#include "Keycodes.h"
|
||||
#include <cwctype> // std::iswspace, std::iswpunct
|
||||
#include <cwctype> // std::iswspace, std::iswpunct, std::iswalnum
|
||||
|
||||
/*
|
||||
todo:
|
||||
optional scrollbars
|
||||
ctrl+left/right to select word
|
||||
double click/ctrl click: word select + drag to select whole words, triple click to select line
|
||||
optional? dragging selected text
|
||||
numerical
|
||||
*/
|
||||
@@ -992,6 +989,11 @@ bool CGUIEditBox::processMouse(const SEvent &event)
|
||||
{
|
||||
switch (event.MouseInput.Event) {
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
if (InhibitLeftMouseUpOnce) {
|
||||
InhibitLeftMouseUpOnce = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Environment->hasFocus(this)) {
|
||||
CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
|
||||
if (MouseMarking) {
|
||||
@@ -1002,6 +1004,61 @@ bool CGUIEditBox::processMouse(const SEvent &event)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EMIE_LMOUSE_DOUBLE_CLICK:
|
||||
// Select the clicked word
|
||||
if (!Text.empty()) {
|
||||
// The cursor is already set by the first EMIE_LMOUSE_PRESSED_DOWN.
|
||||
s32 newMarkBegin = CursorPos,
|
||||
newMarkEnd = CursorPos;
|
||||
|
||||
const bool is_alnum = std::iswalnum(
|
||||
Text[std::min<size_t>(CursorPos, Text.size() - 1)]
|
||||
);
|
||||
for (; newMarkEnd < (s32)Text.size(); ++newMarkEnd) {
|
||||
if (!!std::iswalnum(Text[newMarkEnd]) != is_alnum)
|
||||
break;
|
||||
}
|
||||
for (; newMarkBegin > 0; --newMarkBegin) {
|
||||
if (!!std::iswalnum(Text[newMarkBegin - 1]) != is_alnum)
|
||||
break;
|
||||
}
|
||||
|
||||
setTextMarkers(newMarkBegin, newMarkEnd);
|
||||
// The mouse up event fires afterwards. Prevent selection changes there.
|
||||
InhibitLeftMouseUpOnce = true;
|
||||
MouseMarking = false;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EMIE_LMOUSE_TRIPLE_CLICK:
|
||||
// Select a 'new line'-separated line. This may span multiple broken lines.
|
||||
if (!Text.empty()) {
|
||||
s32 newMarkBegin = CursorPos,
|
||||
newMarkEnd = CursorPos;
|
||||
|
||||
if (MultiLine) {
|
||||
for (; newMarkEnd < (s32)Text.size(); ++newMarkEnd) {
|
||||
wchar_t c = Text[newMarkEnd];
|
||||
if (c == L'\r'|| c == L'\n')
|
||||
break;
|
||||
}
|
||||
|
||||
for (; newMarkBegin > 0; --newMarkBegin) {
|
||||
wchar_t c = Text[newMarkBegin - 1];
|
||||
if (c == '\r' || c == '\n')
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
newMarkBegin = 0;
|
||||
newMarkEnd = Text.size();
|
||||
}
|
||||
|
||||
setTextMarkers(newMarkBegin, newMarkEnd);
|
||||
InhibitLeftMouseUpOnce = true;
|
||||
MouseMarking = false;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EMIE_MOUSE_MOVED: {
|
||||
if (MouseMarking) {
|
||||
CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
|
||||
|
Reference in New Issue
Block a user