fix: horizontal scrollbar missing in console (#2253)

The recent changes to the text editor to fix the longest line length
problems broke the console horizontal scrollbar. The code that displays
the console editor was more complicated that it needed be, and it had
the bad side effect of resetting the cursor which prevented horizontal
scrolling. Adding a function that appends lines to the text editor fixes
all problems and makes the code clearer. To accommodate for strings
containing zeros, the code that inserts text was changed to print a '.'
when zeros are encountered thus keeping the line length the same.
This commit is contained in:
paxcut 2025-05-17 00:23:43 -07:00 committed by GitHub
parent e32c5784af
commit d263962a06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 21 deletions

View File

@ -297,6 +297,9 @@ public:
void JumpToCoords(const Coordinates &coords); void JumpToCoords(const Coordinates &coords);
void SetLongestLineLength(size_t line) { void SetLongestLineLength(size_t line) {
mLongestLineLength = line; mLongestLineLength = line;
}
size_t GetLongestLineLength() const {
return mLongestLineLength;
} }
std::string GetText() const; std::string GetText() const;
bool isEmpty() const { bool isEmpty() const {
@ -383,6 +386,7 @@ public:
void InsertText(const std::string& aValue); void InsertText(const std::string& aValue);
void InsertText(const char* aValue); void InsertText(const char* aValue);
void AppendLine(const std::string &aValue);
void MoveUp(int aAmount = 1, bool aSelect = false); void MoveUp(int aAmount = 1, bool aSelect = false);
void MoveDown(int aAmount = 1, bool aSelect = false); void MoveDown(int aAmount = 1, bool aSelect = false);
@ -547,7 +551,7 @@ private:
Coordinates SanitizeCoordinates(const Coordinates& aValue) const; Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
void Advance(Coordinates& aCoordinates) const; void Advance(Coordinates& aCoordinates) const;
void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd); void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd);
int InsertTextAt(Coordinates& aWhere, const char* aValue); int InsertTextAt(Coordinates& aWhere, const std::string &aValue);
void AddUndo(UndoRecord& aValue); void AddUndo(UndoRecord& aValue);
Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const; Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
Coordinates FindWordStart(const Coordinates& aFrom) const; Coordinates FindWordStart(const Coordinates& aFrom) const;

View File

@ -242,10 +242,21 @@ void TextEditor::DeleteRange(const Coordinates &aStart, const Coordinates &aEnd)
mTextChanged = true; mTextChanged = true;
} }
int TextEditor::InsertTextAt(Coordinates & /* inout */ aWhere, const char *aValue) { void TextEditor::AppendLine(const std::string &aValue) {
if (mLines.size() != 1 || !mLines[0].empty())
mLines.push_back(Line());
Coordinates lastLine = {( int )mLines.size() - 1, 0};
InsertTextAt(lastLine, aValue);
SetCursorPosition({( int )mLines.size() - 1, 0});
EnsureCursorVisible();
mTextChanged = true;
}
int TextEditor::InsertTextAt(Coordinates & /* inout */ aWhere, const std::string &aValueString) {
int cindex = GetCharacterIndex(aWhere); int cindex = GetCharacterIndex(aWhere);
int totalLines = 0; int totalLines = 0;
while (*aValue != '\0') { auto aValue = aValueString.begin();
while (aValue != aValueString.end()) {
if (mLines.empty()) { if (mLines.empty()) {
mLines.push_back(Line()); mLines.push_back(Line());
mTextChanged = true; mTextChanged = true;
@ -279,10 +290,15 @@ int TextEditor::InsertTextAt(Coordinates & /* inout */ aWhere, const char *aValu
cindex = 0; cindex = 0;
++totalLines; ++totalLines;
++aValue; ++aValue;
} else if (*aValue == 0) {
auto &line = mLines[aWhere.mLine];
line.insert(line.begin() + cindex++, Glyph('.', PaletteIndex::Default));
++aWhere.mColumn;
++aValue;
} else { } else {
auto &line = mLines[aWhere.mLine]; auto &line = mLines[aWhere.mLine];
auto d = UTF8CharLength(*aValue); auto d = UTF8CharLength(*aValue);
while (d-- > 0 && *aValue != '\0') while (d-- > 0 && aValue != aValueString.end())
line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default)); line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default));
++aWhere.mColumn; ++aWhere.mColumn;
} }
@ -1587,7 +1603,7 @@ void TextEditor::InsertText(const char *aValue) {
int totalLines = pos.mLine - start.mLine; int totalLines = pos.mLine - start.mLine;
auto text = PreprocessText(aValue); auto text = PreprocessText(aValue);
totalLines += InsertTextAt(pos, text.c_str()); totalLines += InsertTextAt(pos, text);
SetSelection(pos, pos); SetSelection(pos, pos);
SetCursorPosition(pos); SetCursorPosition(pos);
@ -3119,7 +3135,7 @@ void TextEditor::UndoRecord::Undo(TextEditor *aEditor) {
if (!mRemoved.empty()) { if (!mRemoved.empty()) {
auto start = mRemovedStart; auto start = mRemovedStart;
aEditor->InsertTextAt(start, mRemoved.c_str()); aEditor->InsertTextAt(start, mRemoved);
aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 2); aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 2);
} }
@ -3135,7 +3151,7 @@ void TextEditor::UndoRecord::Redo(TextEditor *aEditor) {
if (!mAdded.empty()) { if (!mAdded.empty()) {
auto start = mAddedStart; auto start = mAddedStart;
aEditor->InsertTextAt(start, mAdded.c_str()); aEditor->InsertTextAt(start, mAdded);
aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 1); aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 1);
} }

View File

@ -261,6 +261,7 @@ namespace hex::plugin::builtin {
PerProvider<TextEditor::Coordinates> m_consoleCursorPosition; PerProvider<TextEditor::Coordinates> m_consoleCursorPosition;
PerProvider<TextEditor::Selection> m_selection; PerProvider<TextEditor::Selection> m_selection;
PerProvider<TextEditor::Selection> m_consoleSelection; PerProvider<TextEditor::Selection> m_consoleSelection;
PerProvider<size_t> m_consoleLongestLineLength;
PerProvider<TextEditor::Breakpoints> m_breakpoints; PerProvider<TextEditor::Breakpoints> m_breakpoints;
PerProvider<std::optional<pl::core::err::PatternLanguageError>> m_lastEvaluationError; PerProvider<std::optional<pl::core::err::PatternLanguageError>> m_lastEvaluationError;
PerProvider<std::vector<pl::core::err::CompileError>> m_lastCompileError; PerProvider<std::vector<pl::core::err::CompileError>> m_lastCompileError;

View File

@ -1074,27 +1074,17 @@ namespace hex::plugin::builtin {
} }
if (m_consoleNeedsUpdate) { if (m_consoleNeedsUpdate) {
std::scoped_lock lock(m_logMutex); std::scoped_lock lock(m_logMutex);
bool skipNewLine = false;
auto lineCount = m_consoleEditor.GetTextLines().size(); auto lineCount = m_consoleEditor.GetTextLines().size();
if (m_console->size() < lineCount || (lineCount == 1 && m_consoleEditor.GetLineText(0).empty())) { if (m_console->size() < lineCount || (lineCount == 1 && m_consoleEditor.GetLineText(0).empty())) {
m_consoleEditor.SetText(""); m_consoleEditor.SetText("");
lineCount = 0; lineCount = 0;
skipNewLine = true;
} }
m_consoleEditor.JumpToLine(lineCount);
const auto linesToAdd = m_console->size() - lineCount; const auto linesToAdd = m_console->size() - lineCount;
std::string content;
for (size_t i = 0; i < linesToAdd; i += 1) { for (size_t i = 0; i < linesToAdd; i += 1) {
if (!skipNewLine) m_consoleEditor.AppendLine(m_console->at(lineCount + i));
content += '\n';
skipNewLine = false;
content += m_console->at(lineCount + i);
} }
m_consoleEditor.InsertText(content);
m_consoleNeedsUpdate = false; m_consoleNeedsUpdate = false;
} }
@ -1907,6 +1897,7 @@ namespace hex::plugin::builtin {
m_consoleEditor.ClearActionables(); m_consoleEditor.ClearActionables();
m_console.get(provider).clear(); m_console.get(provider).clear();
m_consoleLongestLineLength.get(provider) = 0;
m_consoleNeedsUpdate = true; m_consoleNeedsUpdate = true;
m_sectionWindowDrawer.clear(); m_sectionWindowDrawer.clear();
@ -1977,7 +1968,10 @@ namespace hex::plugin::builtin {
default: break; default: break;
} }
} }
if (m_consoleLongestLineLength.get(provider) < line.size()) {
m_consoleLongestLineLength.get(provider) = line.size();
m_consoleEditor.SetLongestLineLength(line.size());
}
m_console.get(provider).emplace_back(line); m_console.get(provider).emplace_back(line);
m_consoleNeedsUpdate = true; m_consoleNeedsUpdate = true;
} }
@ -2063,6 +2057,7 @@ namespace hex::plugin::builtin {
m_selection.set(m_textEditor.GetSelection(),oldProvider); m_selection.set(m_textEditor.GetSelection(),oldProvider);
m_consoleCursorPosition.set(m_consoleEditor.GetCursorPosition(),oldProvider); m_consoleCursorPosition.set(m_consoleEditor.GetCursorPosition(),oldProvider);
m_consoleSelection.set(m_consoleEditor.GetSelection(),oldProvider); m_consoleSelection.set(m_consoleEditor.GetSelection(),oldProvider);
m_consoleLongestLineLength.set(m_consoleEditor.GetLongestLineLength(),oldProvider);
m_breakpoints.set(m_textEditor.GetBreakpoints(),oldProvider); m_breakpoints.set(m_textEditor.GetBreakpoints(),oldProvider);
} }
@ -2074,11 +2069,13 @@ namespace hex::plugin::builtin {
m_textEditor.SetBreakpoints(m_breakpoints.get(newProvider)); m_textEditor.SetBreakpoints(m_breakpoints.get(newProvider));
m_consoleEditor.SetText(hex::combineStrings(m_console.get(newProvider), "\n")); m_consoleEditor.SetText(hex::combineStrings(m_console.get(newProvider), "\n"));
m_consoleEditor.SetCursorPosition(m_consoleCursorPosition.get(newProvider)); m_consoleEditor.SetCursorPosition(m_consoleCursorPosition.get(newProvider));
m_consoleEditor.SetLongestLineLength(m_consoleLongestLineLength.get(newProvider));
selection = m_consoleSelection.get(newProvider); selection = m_consoleSelection.get(newProvider);
m_consoleEditor.SetSelection(selection.mStart, selection.mEnd); m_consoleEditor.SetSelection(selection.mStart, selection.mEnd);
} else { } else {
m_textEditor.SetText(""); m_textEditor.SetText("");
m_consoleEditor.SetText(""); m_consoleEditor.SetText("");
m_consoleEditor.SetLongestLineLength(0);
} }
m_textEditor.SetTextChanged(false); m_textEditor.SetTextChanged(false);
@ -2105,8 +2102,7 @@ namespace hex::plugin::builtin {
} }
void ViewPatternEditor::appendEditorText(const std::string &text) { void ViewPatternEditor::appendEditorText(const std::string &text) {
m_textEditor.JumpToLine(m_textEditor.GetTotalLines()); m_textEditor.AppendLine(text);
m_textEditor.InsertText(hex::format("\n{0}", text));
m_triggerEvaluation = true; m_triggerEvaluation = true;
} }