From 007e04bf37e74f0f916484c82575a572b4717762 Mon Sep 17 00:00:00 2001 From: paxcut <53811119+paxcut@users.noreply.github.com> Date: Sun, 16 Feb 2025 05:20:22 -0700 Subject: [PATCH] fix: Auto evaluate not working when undoing changes (#2106) The pattern editor was resetting the flag that marked text changes on every frame, but resolving a text change may take more than one frame, so instead I created a function that allows the resetting of the text changed boolean from view pattern editor. Currently, when a pattern is evaluated the pattern editor will lose focus regardless of how evaluation was triggered. This is specially annoying when using f5 or auto-evaluate. Now whenever a pattern is evaluated, focus is given to the pattern editor when evaluation ends. JumptoLine didn't work for empty lines. Co-authored-by: Nik --- .../ColorTextEditor/include/TextEditor.h | 5 ++-- .../ColorTextEditor/source/TextEditor.cpp | 28 +++++++++++++------ .../content/views/view_pattern_editor.hpp | 1 + .../content/views/view_pattern_editor.cpp | 10 +++++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h index 781bd97be..c45a088ee 100644 --- a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h +++ b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h @@ -299,7 +299,7 @@ public: void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false); void SetText(const std::string& aText); - void JumpToLine(int line); + void JumpToLine(int line=-1); void JumpToCoords(const Coordinates &coords); std::string GetText() const; bool isEmpty() const { @@ -352,6 +352,7 @@ public: void SetReadOnly(bool aValue); bool IsReadOnly() const { return mReadOnly; } bool IsTextChanged() const { return mTextChanged; } + void SetTextChanged(bool aValue=false) { mTextChanged = aValue; } bool IsCursorPositionChanged() const { return mCursorPositionChanged; } bool IsBreakpointsChanged() const { return mBreakPointsChanged; } void ClearBreakpointsChanged() { mBreakPointsChanged = false; } @@ -578,7 +579,7 @@ private: void HandleKeyboardInputs(); void HandleMouseInputs(); void RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPos, const ImVec2 &textEditorSize); - + void SetFocus(); float mLineSpacing = 1.0F; Lines mLines; EditorState mState = {}; diff --git a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp index 15c93f69c..29674a9c2 100644 --- a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp +++ b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp @@ -865,6 +865,16 @@ inline void TextUnformattedColoredAt(const ImVec2 &pos, const ImU32 &color, cons ImGui::PopStyleColor(); } +void TextEditor::SetFocus() { + mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = mFocusAtCoords; + mSelectionMode = SelectionMode::Normal; + SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); + ResetCursorBlinkTime(); + EnsureCursorVisible(); + ImGui::SetKeyboardFocusHere(-1); + mUpdateFocus = false; +} + void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPos, const ImVec2 &textEditorSize) { /* Compute mCharAdvance regarding scaled font size (Ctrl + mouse wheel)*/ const float fontSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, "#", nullptr, nullptr).x; @@ -1068,6 +1078,10 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo auto prevColor = line.empty() ? mPalette[(int)PaletteIndex::Default] : GetGlyphColor(line[0]); ImVec2 bufferOffset; + if (mUpdateFocus && mFocusAtCoords == Coordinates(lineNo, 0)) { + SetFocus(); + } + for (int i = 0; i < line.size();) { auto &glyph = line[i]; auto color = GetGlyphColor(glyph); @@ -1106,13 +1120,7 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo prevColor = color; if (mUpdateFocus && mFocusAtCoords == Coordinates(lineNo, i)) { - mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = mFocusAtCoords; - mSelectionMode = SelectionMode::Normal; - SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); - ResetCursorBlinkTime(); - EnsureCursorVisible(); - ImGui::SetKeyboardFocusHere(-1); - mUpdateFocus = false; + SetFocus(); } if (glyph.mChar == '\t') { @@ -1206,7 +1214,6 @@ void TextEditor::RenderText(const char *aTitle, const ImVec2 &lineNumbersStartPo void TextEditor::Render(const char *aTitle, const ImVec2 &aSize, bool aBorder) { mWithinRender = true; - mTextChanged = false; mCursorPositionChanged = false; auto scrollBg = ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarBg); @@ -1634,7 +1641,10 @@ void TextEditor::DeleteSelection() { } void TextEditor::JumpToLine(int line) { - auto newPos = Coordinates(line, 0); + auto newPos = mState.mCursorPosition; + if (line != -1) { + newPos = Coordinates(line , 0); + } JumpToCoords(newPos); } diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 41b772dfe..71cf441a1 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -286,6 +286,7 @@ namespace hex::plugin::builtin { bool m_replaceMode = false; bool m_openFindReplacePopUp = false; bool m_openGotoLinePopUp = false; + bool m_patternEvaluating = false; std::map m_patternNames; ImRect m_textEditorHoverBox; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 952e12983..50ab54e6e 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -579,7 +579,7 @@ namespace hex::plugin::builtin { } } - if (m_textEditor.IsTextChanged()) { + if (m_textEditor.IsTextChanged() && !m_hasUnevaluatedChanges) { m_hasUnevaluatedChanges = true; m_lastEditorChangeTime = std::chrono::steady_clock::now(); ImHexApi::Provider::markDirty(); @@ -587,7 +587,6 @@ namespace hex::plugin::builtin { if (m_hasUnevaluatedChanges && m_runningEvaluators == 0 && m_runningParsers == 0) { if ((std::chrono::steady_clock::now() - m_lastEditorChangeTime) > std::chrono::seconds(1LL)) { - m_hasUnevaluatedChanges = false; auto code = m_textEditor.GetText(); EventPatternEditorChanged::post(code); @@ -598,6 +597,8 @@ namespace hex::plugin::builtin { if (m_runAutomatically) m_triggerAutoEvaluate = true; }); + m_hasUnevaluatedChanges = false; + m_textEditor.SetTextChanged(); } } @@ -1088,6 +1089,10 @@ namespace hex::plugin::builtin { ImGui::PopFont(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y + 1_scaled); + if (m_patternEvaluating && m_runningEvaluators == 0) { + m_patternEvaluating = false; + m_textEditor.JumpToLine(); + } } void ViewPatternEditor::drawEnvVars(ImVec2 size, std::list &envVars) { @@ -1899,6 +1904,7 @@ namespace hex::plugin::builtin { m_accessHistory = {}; m_accessHistoryIndex = 0; + m_patternEvaluating = true; EventHighlightingChanged::post();