From d263962a06d57c8dcad58e2004ee31ad5bb900fd Mon Sep 17 00:00:00 2001 From: paxcut <53811119+paxcut@users.noreply.github.com> Date: Sat, 17 May 2025 00:23:43 -0700 Subject: [PATCH] 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. --- .../ColorTextEditor/include/TextEditor.h | 6 +++- .../ColorTextEditor/source/TextEditor.cpp | 28 +++++++++++++++---- .../content/views/view_pattern_editor.hpp | 1 + .../content/views/view_pattern_editor.cpp | 24 +++++++--------- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h index f9beb4339..5b0ddbd86 100644 --- a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h +++ b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h @@ -297,6 +297,9 @@ public: void JumpToCoords(const Coordinates &coords); void SetLongestLineLength(size_t line) { mLongestLineLength = line; + } + size_t GetLongestLineLength() const { + return mLongestLineLength; } std::string GetText() const; bool isEmpty() const { @@ -383,6 +386,7 @@ public: void InsertText(const std::string& aValue); void InsertText(const char* aValue); + void AppendLine(const std::string &aValue); void MoveUp(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; void Advance(Coordinates& aCoordinates) const; 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); Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const; Coordinates FindWordStart(const Coordinates& aFrom) const; diff --git a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp index ede1f1a8e..a53e00a52 100644 --- a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp +++ b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp @@ -242,10 +242,21 @@ void TextEditor::DeleteRange(const Coordinates &aStart, const Coordinates &aEnd) 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 totalLines = 0; - while (*aValue != '\0') { + auto aValue = aValueString.begin(); + while (aValue != aValueString.end()) { if (mLines.empty()) { mLines.push_back(Line()); mTextChanged = true; @@ -279,10 +290,15 @@ int TextEditor::InsertTextAt(Coordinates & /* inout */ aWhere, const char *aValu cindex = 0; ++totalLines; ++aValue; + } else if (*aValue == 0) { + auto &line = mLines[aWhere.mLine]; + line.insert(line.begin() + cindex++, Glyph('.', PaletteIndex::Default)); + ++aWhere.mColumn; + ++aValue; } else { auto &line = mLines[aWhere.mLine]; auto d = UTF8CharLength(*aValue); - while (d-- > 0 && *aValue != '\0') + while (d-- > 0 && aValue != aValueString.end()) line.insert(line.begin() + cindex++, Glyph(*aValue++, PaletteIndex::Default)); ++aWhere.mColumn; } @@ -1587,7 +1603,7 @@ void TextEditor::InsertText(const char *aValue) { int totalLines = pos.mLine - start.mLine; auto text = PreprocessText(aValue); - totalLines += InsertTextAt(pos, text.c_str()); + totalLines += InsertTextAt(pos, text); SetSelection(pos, pos); SetCursorPosition(pos); @@ -3119,7 +3135,7 @@ void TextEditor::UndoRecord::Undo(TextEditor *aEditor) { if (!mRemoved.empty()) { auto start = mRemovedStart; - aEditor->InsertTextAt(start, mRemoved.c_str()); + aEditor->InsertTextAt(start, mRemoved); aEditor->Colorize(mRemovedStart.mLine - 1, mRemovedEnd.mLine - mRemovedStart.mLine + 2); } @@ -3135,7 +3151,7 @@ void TextEditor::UndoRecord::Redo(TextEditor *aEditor) { if (!mAdded.empty()) { auto start = mAddedStart; - aEditor->InsertTextAt(start, mAdded.c_str()); + aEditor->InsertTextAt(start, mAdded); aEditor->Colorize(mAddedStart.mLine - 1, mAddedEnd.mLine - mAddedStart.mLine + 1); } diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 71cf441a1..f52a97422 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -261,6 +261,7 @@ namespace hex::plugin::builtin { PerProvider m_consoleCursorPosition; PerProvider m_selection; PerProvider m_consoleSelection; + PerProvider m_consoleLongestLineLength; PerProvider m_breakpoints; PerProvider> m_lastEvaluationError; PerProvider> m_lastCompileError; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index b11e2cd03..71810f55e 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1074,27 +1074,17 @@ namespace hex::plugin::builtin { } if (m_consoleNeedsUpdate) { std::scoped_lock lock(m_logMutex); - bool skipNewLine = false; auto lineCount = m_consoleEditor.GetTextLines().size(); if (m_console->size() < lineCount || (lineCount == 1 && m_consoleEditor.GetLineText(0).empty())) { m_consoleEditor.SetText(""); lineCount = 0; - skipNewLine = true; } - m_consoleEditor.JumpToLine(lineCount); const auto linesToAdd = m_console->size() - lineCount; - - std::string content; for (size_t i = 0; i < linesToAdd; i += 1) { - if (!skipNewLine) - content += '\n'; - skipNewLine = false; - content += m_console->at(lineCount + i); + m_consoleEditor.AppendLine(m_console->at(lineCount + i)); } - m_consoleEditor.InsertText(content); - m_consoleNeedsUpdate = false; } @@ -1907,6 +1897,7 @@ namespace hex::plugin::builtin { m_consoleEditor.ClearActionables(); m_console.get(provider).clear(); + m_consoleLongestLineLength.get(provider) = 0; m_consoleNeedsUpdate = true; m_sectionWindowDrawer.clear(); @@ -1977,7 +1968,10 @@ namespace hex::plugin::builtin { 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_consoleNeedsUpdate = true; } @@ -2063,6 +2057,7 @@ namespace hex::plugin::builtin { m_selection.set(m_textEditor.GetSelection(),oldProvider); m_consoleCursorPosition.set(m_consoleEditor.GetCursorPosition(),oldProvider); m_consoleSelection.set(m_consoleEditor.GetSelection(),oldProvider); + m_consoleLongestLineLength.set(m_consoleEditor.GetLongestLineLength(),oldProvider); m_breakpoints.set(m_textEditor.GetBreakpoints(),oldProvider); } @@ -2074,11 +2069,13 @@ namespace hex::plugin::builtin { m_textEditor.SetBreakpoints(m_breakpoints.get(newProvider)); m_consoleEditor.SetText(hex::combineStrings(m_console.get(newProvider), "\n")); m_consoleEditor.SetCursorPosition(m_consoleCursorPosition.get(newProvider)); + m_consoleEditor.SetLongestLineLength(m_consoleLongestLineLength.get(newProvider)); selection = m_consoleSelection.get(newProvider); m_consoleEditor.SetSelection(selection.mStart, selection.mEnd); } else { m_textEditor.SetText(""); m_consoleEditor.SetText(""); + m_consoleEditor.SetLongestLineLength(0); } m_textEditor.SetTextChanged(false); @@ -2105,8 +2102,7 @@ namespace hex::plugin::builtin { } void ViewPatternEditor::appendEditorText(const std::string &text) { - m_textEditor.JumpToLine(m_textEditor.GetTotalLines()); - m_textEditor.InsertText(hex::format("\n{0}", text)); + m_textEditor.AppendLine(text); m_triggerEvaluation = true; }