[+] Initial unified handling of control, shift, selection, backspace handling under ConsoleTTY
This commit is contained in:
parent
d2ad4cd10d
commit
fc097de2da
@ -28,10 +28,270 @@ namespace Aurora::Console::ConsoleTTY
|
||||
static bool gBuggyFastAppend { false };
|
||||
|
||||
#if 1
|
||||
AuUInt32 GuessWidth(const AuString &referenceLine)
|
||||
{
|
||||
return AuUInt32(AuLocale::ConvertFromUTF8(referenceLine).size());
|
||||
}
|
||||
|
||||
|
||||
TTYConsoleField::TTYConsoleField(TTYConsole *pParent) :
|
||||
pParent(pParent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TTYConsoleField::AddString(const AuString &input)
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
{
|
||||
this->inputField += input;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto itr = this->inputField.begin();
|
||||
std::advance(itr, this->noncanonicalCursorPosInBytes);
|
||||
this->inputField.insert(itr, input.begin(), input.end());
|
||||
}
|
||||
|
||||
this->noncanonicalCursorPos += GuessWidth(input);
|
||||
this->noncanonicalCursorPosInBytes += (int)input.size();
|
||||
}
|
||||
|
||||
void TTYConsoleField::DoUnselectTick()
|
||||
{
|
||||
this->bIsSelecting = false;
|
||||
AuResetMember(this->highlightEndInBytes);
|
||||
AuResetMember(this->highlightEndInPos);
|
||||
AuResetMember(this->highlightStartInBytes);
|
||||
AuResetMember(this->highlightStart);
|
||||
}
|
||||
|
||||
void TTYConsoleField::WriteBuffered(TTYConsole *pConsole, AuPair<AuUInt32, AuUInt32> pos)
|
||||
{
|
||||
if (this->highlightStartInBytes)
|
||||
{
|
||||
auto sViewZero = this->inputField.substr(0, this->highlightStartInBytes.value());
|
||||
auto sViewOne = this->inputField.substr(this->highlightStartInBytes.value(), this->highlightEndInBytes.value() - this->highlightStartInBytes.value());
|
||||
auto sViewTwo = this->highlightEndInBytes.value() < this->inputField.size() ?
|
||||
this->inputField.substr(this->highlightEndInBytes.value()) :
|
||||
"";
|
||||
|
||||
|
||||
pConsole->WriteBufferedEx({ pos.first, pos.second }, AuConsole::EAnsiColor::eWhite, sViewZero);
|
||||
pConsole->WriteBufferedEx({ pos.first + GuessWidth(sViewZero), pos.second }, AuConsole::EAnsiColor::eGreen, sViewOne);
|
||||
pConsole->WriteBufferedEx({ pos.first + GuessWidth(sViewZero) + GuessWidth(sViewOne), pos.second }, AuConsole::EAnsiColor::eWhite, sViewTwo);
|
||||
}
|
||||
else
|
||||
{
|
||||
pConsole->WriteBuffered(pos, this->inputField);
|
||||
}
|
||||
}
|
||||
|
||||
void TTYConsoleField::Clear()
|
||||
{
|
||||
AuResetMember(this->highlightStartInBytes);
|
||||
AuResetMember(this->highlightEndInBytes);
|
||||
AuResetMember(this->highlightEndInPos);
|
||||
AuResetMember(this->highlightStart);
|
||||
AuResetMember(this->highlightChars);
|
||||
this->inputField.clear();
|
||||
this->noncanonicalCursorPos = 0;
|
||||
this->noncanonicalCursorPosInBytes = 0;
|
||||
}
|
||||
|
||||
bool TTYConsoleField::Backspace()
|
||||
{
|
||||
if (this->highlightStartInBytes)
|
||||
{
|
||||
int idx = highlightStartInBytes.value();
|
||||
int endCnt = highlightEndInBytes.value() - idx;
|
||||
|
||||
auto sViewZero = this->inputField.substr(0, this->highlightStartInBytes.value());
|
||||
auto sViewTwo = this->highlightEndInBytes.value() < this->inputField.size() ?
|
||||
this->inputField.substr(this->highlightEndInBytes.value()) :
|
||||
"";
|
||||
|
||||
this->inputField = sViewZero + sViewTwo;
|
||||
|
||||
this->noncanonicalCursorPos = this->highlightStart.value();
|
||||
this->noncanonicalCursorPosInBytes = this->highlightStartInBytes.value();
|
||||
|
||||
DoUnselectTick();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx = AuLocale::Encoding::CountUTF8Length({ this->inputField.data(), AuUInt(this->noncanonicalCursorPosInBytes - 1) }, true);
|
||||
int endCnt = AuLocale::Encoding::CountUTF8Length({ this->inputField.data() + idx, this->inputField.size() - idx }, true);
|
||||
|
||||
if (!endCnt)
|
||||
{
|
||||
this->inputField.resize(idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto suffix = inputField.substr(noncanonicalCursorPosInBytes);
|
||||
this->inputField.resize(idx);
|
||||
this->inputField += suffix;
|
||||
}
|
||||
|
||||
this->noncanonicalCursorPos--;
|
||||
this->noncanonicalCursorPosInBytes = idx;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TTYConsoleField::DirectionalArrow(int iDirection, bool bShift, bool bControl)
|
||||
{
|
||||
if (this->bIsSelecting)
|
||||
{
|
||||
if (this->iLastDirection != iDirection)
|
||||
{
|
||||
this->iLastDirection = iDirection;
|
||||
DoUnselectTick();
|
||||
}
|
||||
}
|
||||
else if (bShift)
|
||||
{
|
||||
this->iLastDirection = iDirection;
|
||||
}
|
||||
|
||||
this->bIsSelecting = bShift;
|
||||
|
||||
auto noncanonicalCursorPos = this->highlightStart ? this->highlightStart.value() : this->noncanonicalCursorPos;
|
||||
auto noncanonicalCursorPosInBytes = this->highlightStart ? this->highlightStartInBytes.value() : this->noncanonicalCursorPosInBytes;
|
||||
|
||||
auto getCurrentChar = [=](int Offset) -> int
|
||||
{
|
||||
auto uIndex = this->noncanonicalCursorPosInBytes + Offset;
|
||||
if (uIndex >= this->inputField.size()) return 4;
|
||||
|
||||
if (!(bool)isascii(this->inputField[uIndex]))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ((bool)::isupper(this->inputField[uIndex]))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this->inputField[uIndex] == ' ' ||
|
||||
this->inputField[uIndex] == '(' ||
|
||||
this->inputField[uIndex] == ')' ||
|
||||
this->inputField[uIndex] == ',')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((bool)::isalpha(this->inputField[uIndex]))
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 5;
|
||||
};
|
||||
|
||||
bool bTickAgain {};
|
||||
do
|
||||
{
|
||||
int iCurState;
|
||||
int iNextState;
|
||||
|
||||
if (iDirection == 1)
|
||||
{
|
||||
iCurState = getCurrentChar(0);
|
||||
Right();
|
||||
iNextState = getCurrentChar(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
iCurState = getCurrentChar(-1);
|
||||
Left();
|
||||
iNextState = getCurrentChar(-1);
|
||||
}
|
||||
|
||||
if (bControl)
|
||||
{
|
||||
bTickAgain = iNextState == iCurState;
|
||||
bTickAgain &= (((bool)this->noncanonicalCursorPos) &&
|
||||
(this->noncanonicalCursorPosInBytes < this->inputField.size()));
|
||||
}
|
||||
}
|
||||
while (bTickAgain);
|
||||
|
||||
if (this->bIsSelecting)
|
||||
{
|
||||
auto uEnd1 = AuMax(this->noncanonicalCursorPos, noncanonicalCursorPos);
|
||||
auto uEnd2 = AuMax(this->noncanonicalCursorPosInBytes, noncanonicalCursorPosInBytes);
|
||||
|
||||
if (this->highlightEndInPos)
|
||||
{
|
||||
uEnd1 = AuMax(uEnd1, this->highlightEndInPos.value());
|
||||
}
|
||||
|
||||
if (this->highlightEndInBytes)
|
||||
{
|
||||
uEnd2 = AuMax(uEnd1, this->highlightEndInBytes.value());
|
||||
}
|
||||
|
||||
auto uStart1 = AuMin(this->noncanonicalCursorPos, noncanonicalCursorPos);
|
||||
auto uStart2 = AuMin(this->noncanonicalCursorPosInBytes, noncanonicalCursorPosInBytes);
|
||||
|
||||
this->highlightStartInBytes = uStart2;
|
||||
this->highlightEndInBytes = uEnd2;
|
||||
this->highlightEndInPos = uEnd1;
|
||||
this->highlightStart = uStart1;
|
||||
this->highlightChars = AuLocale::Encoding::CountUTF8Length({ this->inputField.data() + uStart2, (AuUInt)uEnd2 - uStart2 }, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoUnselectTick();
|
||||
}
|
||||
}
|
||||
|
||||
void TTYConsoleField::Left()
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int idx = AuLocale::Encoding::CountUTF8Length({ this->inputField.data(), AuUInt(this->noncanonicalCursorPosInBytes - 1) },
|
||||
true);
|
||||
|
||||
this->noncanonicalCursorPos--;
|
||||
this->noncanonicalCursorPosInBytes = idx;
|
||||
}
|
||||
|
||||
void TTYConsoleField::Right()
|
||||
{
|
||||
if (this->inputField.size() <= this->noncanonicalCursorPosInBytes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto uAddend = AuLocale::Encoding::IterateUTF8({ &this->inputField[this->noncanonicalCursorPosInBytes],
|
||||
this->inputField.size() - this->noncanonicalCursorPosInBytes });
|
||||
|
||||
this->noncanonicalCursorPos++;
|
||||
this->noncanonicalCursorPosInBytes += uAddend;
|
||||
}
|
||||
|
||||
TTYConsole::TTYConsole() :
|
||||
inputField(this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool TTYConsole::IsShowingHintLine()
|
||||
{
|
||||
return this->inputField.size();
|
||||
return false;
|
||||
//return this->inputField.inputField.size();
|
||||
}
|
||||
|
||||
void TTYConsole::Init()
|
||||
@ -165,12 +425,12 @@ namespace Aurora::Console::ConsoleTTY
|
||||
}
|
||||
case ConsoleStd::ENoncanonicalInput::eArrowLeft:
|
||||
{
|
||||
NoncanonicalOnLeft();
|
||||
NoncanonicalOnLeft(input.bIsShiftSequence || input.bIsAltSequence, input.bIsControlSequence);
|
||||
break;
|
||||
}
|
||||
case ConsoleStd::ENoncanonicalInput::eArrowRight:
|
||||
{
|
||||
NoncanonicalOnRight();
|
||||
NoncanonicalOnRight(input.bIsShiftSequence || input.bIsAltSequence, input.bIsControlSequence);
|
||||
break;
|
||||
}
|
||||
case ConsoleStd::ENoncanonicalInput::ePageDown:
|
||||
@ -186,9 +446,9 @@ namespace Aurora::Console::ConsoleTTY
|
||||
case ConsoleStd::ENoncanonicalInput::eArrowDown:
|
||||
{
|
||||
|
||||
if (this->noncanonicalCursorPosInBytes == 0 ||
|
||||
if (this->inputField.noncanonicalCursorPosInBytes == 0 ||
|
||||
this->GetHintLines() == 0 ||
|
||||
this->noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
this->inputField.noncanonicalCursorPosInBytes == this->inputField.inputField.size())
|
||||
{
|
||||
NoncanonicalOnHistoryDown();
|
||||
}
|
||||
@ -202,9 +462,9 @@ namespace Aurora::Console::ConsoleTTY
|
||||
case ConsoleStd::ENoncanonicalInput::eArrowUp:
|
||||
{
|
||||
|
||||
if (this->noncanonicalCursorPosInBytes == 0 ||
|
||||
if (this->inputField.noncanonicalCursorPosInBytes == 0 ||
|
||||
this->GetHintLines() == 0 ||
|
||||
this->noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
this->inputField.noncanonicalCursorPosInBytes == this->inputField.inputField.size())
|
||||
{
|
||||
NoncanonicalOnHistoryUp();
|
||||
}
|
||||
@ -236,91 +496,35 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
void TTYConsole::NoncanonicalOnString(const AuString &input)
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
{
|
||||
this->inputField += input;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto itr = this->inputField.begin();
|
||||
std::advance(itr, this->noncanonicalCursorPosInBytes);
|
||||
this->inputField.insert(itr, input.begin(), input.end());
|
||||
}
|
||||
|
||||
this->noncanonicalCursorPos += GuessWidth(input);
|
||||
this->noncanonicalCursorPosInBytes += (int)input.size();
|
||||
inputField.AddString(input);
|
||||
|
||||
RedrawInput(true);
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
|
||||
void TTYConsole::NoncanonicalOnLeft()
|
||||
void TTYConsole::NoncanonicalOnLeft(bool bShift, bool bControl)
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes <= 0)
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes == -1)
|
||||
{
|
||||
NoncanonicalOnMenuLeft();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = AuLocale::Encoding::CountUTF8Length({this->inputField.data(), AuUInt(this->noncanonicalCursorPosInBytes - 1)}, true);
|
||||
|
||||
this->noncanonicalCursorPos--;
|
||||
this->noncanonicalCursorPosInBytes = idx;
|
||||
inputField.DirectionalArrow(-1, bShift, bControl);
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
|
||||
void TTYConsole::NoncanonicalOnRight()
|
||||
void TTYConsole::NoncanonicalOnRight(bool bShift, bool bControl)
|
||||
{
|
||||
if (this->noncanonicalCursorPosInBytes == -1)
|
||||
{
|
||||
NoncanonicalOnMenuRight();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto uAddend = AuLocale::Encoding::IterateUTF8({ &this->inputField[this->noncanonicalCursorPosInBytes], this->inputField.size() - this->noncanonicalCursorPosInBytes });
|
||||
|
||||
this->noncanonicalCursorPos++;
|
||||
this->noncanonicalCursorPosInBytes += uAddend;
|
||||
inputField.DirectionalArrow(1, bShift, bControl);
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
|
||||
void TTYConsole::NoncanonicalOnBackspace()
|
||||
{
|
||||
if (noncanonicalCursorPosInBytes <= 0)
|
||||
if (!inputField.Backspace())
|
||||
{
|
||||
return;
|
||||
}
|
||||
int idx = AuLocale::Encoding::CountUTF8Length({this->inputField.data(), AuUInt(this->noncanonicalCursorPosInBytes - 1)}, true);
|
||||
int endCnt = AuLocale::Encoding::CountUTF8Length({this->inputField.data() + idx, this->inputField.size() - idx}, true);
|
||||
|
||||
|
||||
if (!endCnt)
|
||||
{
|
||||
this->inputField.resize(idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto suffix = inputField.substr(noncanonicalCursorPosInBytes);
|
||||
this->inputField.resize(idx);
|
||||
this->inputField += suffix;
|
||||
}
|
||||
|
||||
this->noncanonicalCursorPos--;
|
||||
this->noncanonicalCursorPosInBytes = idx;
|
||||
|
||||
RedrawInput(true);
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
|
||||
|
||||
bool TTYConsole::IsWin32UxMode()
|
||||
{
|
||||
return true;
|
||||
@ -427,26 +631,26 @@ namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
AU_LOCK_GUARD(this->historyLock->AsWritable());
|
||||
|
||||
if (this->inputField.size())
|
||||
if (this->inputField.inputField.size())
|
||||
{
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
if (this->inputField == "!s")
|
||||
if (this->inputField.inputField == "!s")
|
||||
{
|
||||
EnterScrollMode();
|
||||
}
|
||||
else if (this->inputField == "!c")
|
||||
else if (this->inputField.inputField == "!c")
|
||||
{
|
||||
LeaveScrollMode();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (this->inputField == "!b")
|
||||
if (this->inputField.inputField == "!b")
|
||||
{
|
||||
this->iScrollPos = -1;
|
||||
this->bTriggerRedraw = true;
|
||||
}
|
||||
else if (this->inputField == "!t")
|
||||
else if (this->inputField.inputField == "!t")
|
||||
{
|
||||
this->iScrollPos = 0;
|
||||
this->bTriggerRedraw = true;
|
||||
@ -454,31 +658,29 @@ namespace Aurora::Console::ConsoleTTY
|
||||
else
|
||||
{
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
if (this->inputField == "help")
|
||||
if (this->inputField.inputField == "help")
|
||||
{
|
||||
AuLogInfo("ConsoleTTY: Type !s to enter scroll mode, type !c to enter host-os controlled copy/paste mode (quick-edit)");
|
||||
}
|
||||
#endif
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
if (this->inputField == "help")
|
||||
if (this->inputField.inputField == "help")
|
||||
{
|
||||
AuLogInfo("ConsoleTTY: Hold control + arrow key up/down to scroll.");
|
||||
}
|
||||
#endif
|
||||
if (this->inputField == "help")
|
||||
if (this->inputField.inputField == "help")
|
||||
{
|
||||
AuLogInfo("ConsoleTTY: use the command !t to scroll to the top, the command !b to lock-scroll to the bottom.");
|
||||
}
|
||||
|
||||
AuConsole::DispatchRawLine(this->inputField);
|
||||
AuConsole::DispatchRawLine(this->inputField.inputField);
|
||||
}
|
||||
}
|
||||
|
||||
AuTryInsert(this->history, this->inputField);
|
||||
AuTryInsert(this->history, this->inputField.inputField);
|
||||
|
||||
this->noncanonicalCursorPos = 0;
|
||||
this->noncanonicalCursorPosInBytes = 0;
|
||||
this->inputField.clear();
|
||||
this->inputField.Clear();
|
||||
|
||||
OnEnter();
|
||||
}
|
||||
@ -510,8 +712,8 @@ namespace Aurora::Console::ConsoleTTY
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->noncanonicalCursorPos == 0 ||
|
||||
noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
if (this->inputField.noncanonicalCursorPos == 0 ||
|
||||
this->inputField.noncanonicalCursorPosInBytes == this->inputField.inputField.size())
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
@ -529,13 +731,13 @@ namespace Aurora::Console::ConsoleTTY
|
||||
}
|
||||
|
||||
|
||||
this->inputField = this->history[this->iHistoryPos];
|
||||
this->inputField.inputField = this->history[this->iHistoryPos];
|
||||
HistoryUpdateCursor();
|
||||
|
||||
if (locked)
|
||||
{
|
||||
this->noncanonicalCursorPos = GuessWidth(this->inputField);
|
||||
this->noncanonicalCursorPosInBytes = (int)this->inputField.size();
|
||||
this->inputField.noncanonicalCursorPos = GuessWidth(this->inputField.inputField);
|
||||
this->inputField.noncanonicalCursorPosInBytes = (int)this->inputField.inputField.size();
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
}
|
||||
@ -551,8 +753,8 @@ namespace Aurora::Console::ConsoleTTY
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->noncanonicalCursorPos == 0 ||
|
||||
noncanonicalCursorPosInBytes == this->inputField.size())
|
||||
if (this->inputField.noncanonicalCursorPos == 0 ||
|
||||
this->inputField.noncanonicalCursorPosInBytes == this->inputField.inputField.size())
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
@ -567,27 +769,27 @@ namespace Aurora::Console::ConsoleTTY
|
||||
if (this->iHistoryPos >= this->history.size())
|
||||
{
|
||||
this->iHistoryPos = -1;
|
||||
this->inputField.clear();
|
||||
this->inputField.inputField.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->inputField = this->history[this->iHistoryPos];
|
||||
this->inputField.inputField = this->history[this->iHistoryPos];
|
||||
}
|
||||
|
||||
HistoryUpdateCursor();
|
||||
|
||||
if (locked)
|
||||
{
|
||||
this->noncanonicalCursorPos = GuessWidth(this->inputField);
|
||||
this->noncanonicalCursorPosInBytes = (int)this->inputField.size();
|
||||
this->inputField.noncanonicalCursorPos = GuessWidth(this->inputField.inputField);
|
||||
this->inputField.noncanonicalCursorPosInBytes = (int)this->inputField.inputField.size();
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
}
|
||||
|
||||
void TTYConsole::HistoryUpdateCursor()
|
||||
{
|
||||
this->noncanonicalCursorPos = AuMin<AuUInt32>(this->noncanonicalCursorPos, GuessWidth(this->inputField));
|
||||
this->noncanonicalCursorPosInBytes = AuMin<AuUInt32>(this->noncanonicalCursorPosInBytes, AuUInt32(this->inputField.size()));
|
||||
this->inputField.noncanonicalCursorPos = AuMin<AuUInt32>(this->inputField.noncanonicalCursorPos, GuessWidth(this->inputField.inputField));
|
||||
this->inputField.noncanonicalCursorPosInBytes = AuMin<AuUInt32>(this->inputField.noncanonicalCursorPosInBytes, AuUInt32(this->inputField.inputField.size()));
|
||||
RedrawInput(true);
|
||||
NoncanonicalSetCursor();
|
||||
}
|
||||
@ -759,7 +961,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
this->iHistoryPos = -1;
|
||||
auto line = this->currentHeight;
|
||||
this->inputField.clear();
|
||||
this->inputField.Clear();
|
||||
this->RedrawInput(true);
|
||||
this->NoncanonicalSetCursor();
|
||||
}
|
||||
@ -993,7 +1195,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
bool bRedrawWindowRequired = this->bTriggerRedraw;
|
||||
bool bHasMesasgesPending = messagesPending.size() || this->bTriggerRedraw;
|
||||
|
||||
auto currentHash = AuFnv1a64Runtime(inputField.data(), inputField.size());
|
||||
auto currentHash = AuFnv1a64Runtime(inputField.inputField.data(), inputField.inputField.size());
|
||||
bool bInputChanged = NoncanonicalMode() && (lastInputHash != currentHash && lastInputHash != 0);
|
||||
lastInputHash = currentHash;
|
||||
|
||||
@ -1397,10 +1599,6 @@ namespace Aurora::Console::ConsoleTTY
|
||||
WriteBuffered({}, end);
|
||||
}
|
||||
|
||||
AuUInt32 TTYConsole::GuessWidth(const AuString &referenceLine)
|
||||
{
|
||||
return AuUInt32(AuLocale::ConvertFromUTF8(referenceLine).size());
|
||||
}
|
||||
|
||||
const AuString &TTYConsole::Stringify(const AuString &referenceLine, const AlignedString &string, bool spacing, bool brackets, bool extraPadding)
|
||||
{
|
||||
@ -1717,7 +1915,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
if (clear && NoncanonicalMode())
|
||||
{
|
||||
WriteBuffered({this->GetLeftBorder() + this->leftPadding + 1, height}, this->inputField);
|
||||
this->inputField.WriteBuffered(this, { this->GetLeftBorder() + this->leftPadding + 1, height });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1941,7 +2139,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
return {this->GetLeftBorder() + this->leftPadding + 1 + this->leftInputPadding, this->currentHeight - (1 + this->GetBottomBorder())};
|
||||
}
|
||||
|
||||
return {this->GetLeftBorder() + this->leftPadding + 1 + this->leftInputPadding + (noncanonicalCursorPos == -1 ? 0 : noncanonicalCursorPos) /*:(*/, this->currentHeight - (1 + this->GetBottomBorder())}; // { i do not like this, ...}
|
||||
return {this->GetLeftBorder() + this->leftPadding + 1 + this->leftInputPadding + (this->inputField.noncanonicalCursorPos == -1 ? 0 : this->inputField.noncanonicalCursorPos) /*:(*/, this->currentHeight - (1 + this->GetBottomBorder())}; // { i do not like this, ...}
|
||||
}
|
||||
|
||||
AuPair<AuUInt32, AuUInt32> TTYConsole::GetInitialInputLine()
|
||||
|
@ -14,8 +14,44 @@ namespace Aurora::Console::ConsoleTTY
|
||||
void EnterScrollMode();
|
||||
void LeaveScrollMode();
|
||||
|
||||
struct TTYConsole;
|
||||
|
||||
struct TTYConsoleField
|
||||
{
|
||||
TTYConsoleField(TTYConsole *pParent);
|
||||
|
||||
AuString inputField;
|
||||
int noncanonicalCursorPos {};
|
||||
int noncanonicalCursorPosInBytes {};
|
||||
|
||||
void AddString(const AuString &str);
|
||||
bool Backspace();
|
||||
void DirectionalArrow(int iDirection, bool bShift, bool bControl);
|
||||
void Clear();
|
||||
void WriteBuffered(TTYConsole *pConsole, AuPair<AuUInt32, AuUInt32> pos);
|
||||
|
||||
AuOptionalEx<int> highlightStartInBytes {};
|
||||
AuOptionalEx<int> highlightStart {};
|
||||
AuOptionalEx<int> highlightEndInBytes {};
|
||||
AuOptionalEx<int> highlightEndInPos {};
|
||||
int highlightChars {};
|
||||
|
||||
void DoUnselectTick();
|
||||
|
||||
private:
|
||||
|
||||
void Left();
|
||||
void Right();
|
||||
|
||||
TTYConsole *pParent;
|
||||
bool bIsSelecting {};
|
||||
int iLastDirection {};
|
||||
};
|
||||
|
||||
struct TTYConsole : ITTYConsole
|
||||
{
|
||||
TTYConsole();
|
||||
|
||||
void BufferMessage(const AuConsole::ConsoleMessage &msg) override;
|
||||
void BufferMessage(const AuConsole::ConsoleMessage &msg, const AuString &input) ;
|
||||
|
||||
@ -33,6 +69,11 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
bool uxModeFlipped {};
|
||||
|
||||
inline void SignalRedraw()
|
||||
{
|
||||
this->bTriggerRedraw = true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool UTF8();
|
||||
@ -60,8 +101,8 @@ namespace Aurora::Console::ConsoleTTY
|
||||
void NoncanonicalOnString(const AuString &input);
|
||||
void NoncanonicalOnBackspace();
|
||||
void NoncanonicalOnEnter();
|
||||
void NoncanonicalOnLeft();
|
||||
void NoncanonicalOnRight();
|
||||
void NoncanonicalOnLeft(bool bShift, bool bControl);
|
||||
void NoncanonicalOnRight(bool bShift, bool bControl);
|
||||
|
||||
void NoncanonicalOnPageUp();
|
||||
void NoncanonicalOnPageDown();
|
||||
@ -84,8 +125,9 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
AuString historyFileName;
|
||||
|
||||
int noncanonicalCursorPos {};
|
||||
int noncanonicalCursorPosInBytes {};
|
||||
TTYConsoleField inputField;
|
||||
//int noncanonicalCursorPos {};
|
||||
//int noncanonicalCursorPosInBytes {};
|
||||
|
||||
virtual int GetBannerLines();
|
||||
virtual int GetLogBoxLines();
|
||||
@ -170,6 +212,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
private:
|
||||
|
||||
friend struct TTYConsoleField;
|
||||
void DebugLogArea();
|
||||
|
||||
AuList<AuPair<AuString /*autocompletion*/, AuList<AuString/* secondary hint*/>>> hintStrings;
|
||||
@ -209,7 +252,6 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
AuString tempMemory;
|
||||
|
||||
AuUInt32 GuessWidth(const AuString &referenceLine);
|
||||
const AuString &Stringify(const AuString &referenceLine, const AlignedString &string, bool spacing, bool brackets, bool extraPadding);
|
||||
|
||||
|
||||
@ -237,7 +279,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
void UXModeFlip();
|
||||
void UXModeStart();
|
||||
|
||||
AuString inputField {};
|
||||
//AuString inputField {};
|
||||
|
||||
AuUInt32 lastInputHash {};
|
||||
AuUInt32 lastBorderHash {};
|
||||
|
Loading…
Reference in New Issue
Block a user