From 1f2e453e20a00b51e37aca4f00f0131f11e70701 Mon Sep 17 00:00:00 2001 From: paxcut <53811119+paxcut@users.noreply.github.com> Date: Sun, 24 Nov 2024 03:24:14 -0700 Subject: [PATCH] fix: Various pattern editor settings not being per-provider (#1917) ### Problem description Fixes provided for the following unreported bugs. - Environment variables are set to be per provider but used as if they are not. When a project is loaded all the environment variables for each provider are assigned to the first provider making it impossible to add new ones to the other providers. - When switching providers, the text editor selection, the text editor breakpoints, the console text, the console selection and the console cursor position of the old provider are being assigned to the new provider ### Implementation description This PR aims at fixing both errors by: - using variable defined to be per provider so that they affect their provider only when necessary. - creating new per provider variables and using them so that each provider has their own console, selections and breakpoints. In order to support the newly added per provided features new functions were added to the text processor for selections and breakpoints. All the new per provider variables are defined and used in view pattern editor. --- .../ColorTextEditor/include/TextEditor.h | 7 +++++ .../ColorTextEditor/source/TextEditor.cpp | 4 +++ .../content/views/view_pattern_editor.hpp | 4 +++ .../content/views/view_pattern_editor.cpp | 30 ++++++++++++++----- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h index 7e02ac725..7bac39a95 100644 --- a/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h +++ b/lib/third_party/imgui/ColorTextEditor/include/TextEditor.h @@ -189,6 +189,11 @@ public: static const LanguageDefinition& Lua(); }; + struct Selection { + Coordinates mStart; + Coordinates mEnd; + }; + TextEditor(); ~TextEditor(); @@ -199,6 +204,7 @@ public: static void SetPalette(const Palette& aValue); void SetErrorMarkers(const ErrorMarkers& aMarkers) { mErrorMarkers = aMarkers; } + Breakpoints &GetBreakpoints() { return mBreakpoints; } void SetBreakpoints(const Breakpoints& aMarkers) { mBreakpoints = aMarkers; } ImVec2 Underwaves( ImVec2 pos, uint32_t nChars, ImColor color= ImGui::GetStyleColorVec4(ImGuiCol_Text), const ImVec2 &size_arg= ImVec2(0, 0)); @@ -263,6 +269,7 @@ public: void SetSelectionStart(const Coordinates& aPosition); void SetSelectionEnd(const Coordinates& aPosition); void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode = SelectionMode::Normal); + Selection GetSelection() const; void SelectWordUnderCursor(); void SelectAll(); bool HasSelection() const; diff --git a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp index 562dc73c6..f41129506 100644 --- a/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp +++ b/lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp @@ -1482,6 +1482,10 @@ void TextEditor::SetSelection(const Coordinates &aStart, const Coordinates &aEnd mCursorPositionChanged = true; } +TextEditor::Selection TextEditor::GetSelection() const { + return {mState.mSelectionStart, mState.mSelectionEnd}; +} + void TextEditor::SetTabSize(int aValue) { mTabSize = std::max(0, std::min(32, aValue)); } diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 3deb72759..c7dfeb4d2 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -249,6 +249,10 @@ namespace hex::plugin::builtin { std::mutex m_logMutex; PerProvider m_cursorPosition; + PerProvider m_consoleCursorPosition; + PerProvider m_selection; + PerProvider m_consoleSelection; + PerProvider m_breakpoints; PerProvider> m_lastEvaluationError; PerProvider> m_lastCompileError; PerProvider>*> m_callStack; diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 45c137249..976253175 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -412,6 +412,9 @@ namespace hex::plugin::builtin { if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.replace_all"_lang, "",false,!findReplaceHandler->GetReplaceWord().empty())) findReplaceHandler->ReplaceAll(&m_textEditor); + if (ImGui::IsKeyPressed(ImGuiKey_Escape, false)) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); } @@ -1715,11 +1718,11 @@ namespace hex::plugin::builtin { auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock()); m_runningEvaluators += 1; - *m_executionDone = false; + m_executionDone.get(provider) = false; m_textEditor.SetErrorMarkers({}); - m_console->clear(); + m_console.get(provider).clear(); m_consoleNeedsUpdate = true; m_sectionWindowDrawer.clear(); @@ -1770,7 +1773,7 @@ namespace hex::plugin::builtin { return m_dangerousFunctionsAllowed == DangerousFunctionPerms::Allow; }); - runtime.setLogCallback([this](auto level, auto message) { + runtime.setLogCallback([this,provider](auto level, auto message) { std::scoped_lock lock(m_logMutex); for (auto line : wolv::util::splitString(message, "\n")) { @@ -1786,7 +1789,7 @@ namespace hex::plugin::builtin { } } - m_console->emplace_back(line); + m_console.get(provider).emplace_back(line); m_consoleNeedsUpdate = true; } }); @@ -1801,7 +1804,7 @@ namespace hex::plugin::builtin { m_lastEvaluationProcessed = false; std::scoped_lock lock(m_logMutex); - m_console->emplace_back( + m_console.get(provider).emplace_back( hex::format("I: Evaluation took {}", std::chrono::duration(runtime.getLastRunningTime())) ); m_consoleNeedsUpdate = true; @@ -1858,7 +1861,7 @@ namespace hex::plugin::builtin { EventProviderOpened::subscribe(this, [this](prv::Provider *provider) { m_shouldAnalyze.get(provider) = true; - m_envVarEntries->emplace_back(0, "", i128(0), EnvVarType::Integer); + m_envVarEntries.get(provider).emplace_back(0, "", i128(0), EnvVarType::Integer); m_debuggerDrawer.get(provider) = std::make_unique(); m_cursorPosition.get(provider) = TextEditor::Coordinates(0, 0); @@ -1868,13 +1871,26 @@ namespace hex::plugin::builtin { if (oldProvider != nullptr) { m_sourceCode.set(oldProvider, m_textEditor.GetText()); m_cursorPosition.set(m_textEditor.GetCursorPosition(),oldProvider); + m_selection.set(m_textEditor.GetSelection(),oldProvider); + m_consoleCursorPosition.set(m_consoleEditor.GetCursorPosition(),oldProvider); + m_consoleSelection.set(m_consoleEditor.GetSelection(),oldProvider); + m_breakpoints.set(m_textEditor.GetBreakpoints(),oldProvider); } if (newProvider != nullptr) { m_textEditor.SetText(m_sourceCode.get(newProvider)); m_textEditor.SetCursorPosition(m_cursorPosition.get(newProvider)); - } else + TextEditor::Selection selection = m_selection.get(newProvider); + m_textEditor.SetSelection(selection.mStart, selection.mEnd); + m_textEditor.SetBreakpoints(m_breakpoints.get(newProvider)); + m_consoleEditor.SetText(hex::combineStrings(m_console.get(newProvider), "\n")); + m_consoleEditor.SetCursorPosition(m_consoleCursorPosition.get(newProvider)); + selection = m_consoleSelection.get(newProvider); + m_consoleEditor.SetSelection(selection.mStart, selection.mEnd); + } else { m_textEditor.SetText(""); + m_consoleEditor.SetText(""); + } }); RequestAddVirtualFile::subscribe(this, [this](const std::fs::path &path, const std::vector &data, Region region) {