/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ConsoleTTY.hpp Date: 2022-5-11 Author: Reece ***/ #pragma once namespace Aurora::Console::ConsoleTTY { inline bool gTTYConsoleEnabled {}; 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 pos); AuOptionalEx highlightStartInBytes {}; AuOptionalEx highlightStart {}; AuOptionalEx highlightEndInBytes {}; AuOptionalEx 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) ; // void Pump(); void PumpHistory(); bool RedrawWindow(); void OnEnter(); void Init(); void Deinit(); bool Start() override; void End() override; bool uxModeFlipped {}; AuUInt64 uxFlipTime {}; inline void SignalRedraw() { this->bTriggerRedraw = true; } private: bool UTF8(); void SetHintStrings(const AuList>> &hints); void RedrawBorders(); void RedrawLogBox(); void RedrawHintLine(); void RedrawInput(bool clear); void RedrawBanner(); void BlankLogBox(); void SetInitialCursorPos(); bool CheckRedraw(); void PostRedraw(bool first); bool RegenerateBuffer(bool resChanged, bool &redrawBox); bool NoncanonicalMode() override; void NoncanonicalTick(); void NoncanonicalSetCursor(); void NoncanonicalOnString(const AuString &input); void NoncanonicalOnBackspace(); void NoncanonicalOnEnter(); void NoncanonicalOnLeft(bool bShift, bool bControl); void NoncanonicalOnRight(bool bShift, bool bControl); void NoncanonicalOnPageUp(); void NoncanonicalOnPageDown(); void Scroll(int delta); void NoncanonicalOnMenuLeft(); void NoncanonicalOnMenuRight(); void NoncanonicalOnMenuUp(); void NoncanonicalOnMenuDown(); void NoncanonicalOnHistoryUp(); void NoncanonicalOnHistoryDown(); void HistorySetFile(); AuString HistoryGetFile(); void HistoryAppendChanges(); void HistoryLoad(); void HistoryUpdateCursor(); AuString historyFileName; TTYConsoleField inputField; //int noncanonicalCursorPos {}; //int noncanonicalCursorPosInBytes {}; virtual int GetBannerLines(); virtual int GetLogBoxLines(); virtual int GetHintLines(); virtual int GetTextInputLines(); virtual bool GetLogBoxHintBorder(); virtual bool GetBottomBorder() override; AuPair GetLogBoxStart(); AuPair GetHintLine(); AuPair GetInputCursor(); AuPair GetInitialInputLine(); virtual bool GetBannerFootBorder() override; virtual ETTYAlign SetTitleAlignment(ETTYAlign newValue) override; virtual ETTYAlign GetLogBoxTitleAlignment() override; virtual ETTYAlign SetLogBoxTitleAlignment(ETTYAlign newValue) override; virtual bool GetTopBorder() override; virtual bool GetLeftBorder() override; virtual bool GetRightBorder() override; virtual ETTYAlign GetTitleAlignment() override; virtual ETTYAlign GetHeaderAlignment() override; virtual ETTYAlign GetSubheaderAlignment() override; virtual AuString GetHeaderBorderTitle() override; virtual AuString GetLogBoxBorderTitle() override; virtual AuString GetHeader() override; virtual AuString GetSubHeader() override; virtual ETTYAlign SetHeaderAlignment(ETTYAlign newValue) override; virtual ETTYAlign SetSubheaderAlignment(ETTYAlign newValue) override; virtual AuString SetHeaderBorderTitle(const AuString &newValue) override; virtual AuString SetLogBoxBorderTitle(const AuString &newValue) override; virtual AuString SetHeader(const AuString &newValue) override; virtual AuString SetSubHeader(const AuString &newValue) override; virtual bool SetTopBorder(bool newValue) override; virtual bool SetLeftBorder(bool newValue) override; virtual bool SetRightBorder(bool newValue) override; virtual AuUInt8 SetPaddingLeftOfLog(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingRightOfLog(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingLeftOfInput(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingTopOfInput(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingTopOfHint(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingTopOfHeader(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingMidOfHeader(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingBottomOfSubheader(AuUInt8 newValue) override; virtual AuUInt8 GetPaddingLeftOfLog() override; virtual AuUInt8 GetPaddingRightOfLog() override; virtual AuUInt8 GetPaddingLeftOfInput() override; virtual AuUInt8 GetPaddingTopOfInput() override; virtual AuUInt8 GetPaddingTopOfHint() override; virtual AuUInt8 GetPaddingTopOfHeader() override; virtual AuUInt8 GetPaddingMidOfHeader() override; virtual AuUInt8 GetPaddingBottomOfSubheader() override; virtual AuUInt8 SetPaddingHeadOfLog(AuUInt8 newValue) override; virtual AuUInt8 SetPaddingTopOfLog(AuUInt8 newValue) override; virtual AuUInt8 GetPaddingHeadOfLog() override; virtual AuUInt8 GetPaddingTopOfLog() override; void WriteBufferedEx(AuPair pos, EAnsiColor color, const AuString &in); void WriteBuffered(AuPair pos, const AuString &in); void WriteLine(int Y, const AuString &in); void BlankLine(int Y, bool borders = true); void BlankBordersLine(int Y); bool PermitDoubleBuffering(); private: friend struct TTYConsoleField; void DebugLogArea(); AuList>> hintStrings; void Flush(); int currentWidth {}; int currentHeight {}; int oldWidth {}; int oldHeight {}; int iHistoryPos {-1}; int iHistoryWritePos {0}; AuList history; AuRWLock historyLock; AuMutex messageLock; AuList messagesPending; AuList messages; AuList> screenBuffer; bool bScreenBufferDoesntMap {}; int iScrollPos { -1 }; AuPair cursorPos; struct AlignedString { AuString str; ETTYAlign align {}; }; AuString tempMemory; const AuString &Stringify(const AuString &referenceLine, const AlignedString &string, bool spacing, bool brackets, bool extraPadding); AlignedString header; AlignedString subheader; AlignedString headerTitle; AlignedString logTitle; bool bTriggerRedraw {}; bool bRightBorder {true}; bool bLeftBorder {true}; bool bTopBorder {true}; bool bShouldShowBorders {}; bool bShowingBorders {}; bool IsShowingHintLine(); bool bIsShowingHintLine; bool IsWin32UxMode(); void UXModeFlip(); void UXModeStart(); //AuString inputField {}; AuUInt32 lastInputHash {}; AuUInt32 lastBorderHash {}; int leftPadding {1}; int rightPadding {1}; int leftLogPadding {1}; int rightLogPadding {1}; int topLogPadding {0}; // extra padding, if displaying header ... int topLogPaddingExtra {1}; // this is backwards ... int leftInputPadding {0}; int topInputPadding {0}; int topHintPadding {0}; int topHeaderPadding {0}; int midHeaderPadding {0}; int bottomSubHeaderPadding {0}; AuUInt32 oldCP {}; }; inline TTYConsole gTTYConsole; void Init(); void Pump(); void Exit(); void OnEnter(); void WriteTTYOut(const AuConsole::ConsoleMessage &msg); void WriteTTYOut(const AuConsole::ConsoleMessage &msg, const AuString &input); AUKN_SYM AuSPtr GetTTYConsole(); void PumpForce(); }