From e0180b718f9bffcae55fabbacb839ea465fee2b5 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 24 Jul 2025 23:29:13 +0200 Subject: [PATCH] feat: Added simplified pattern value editor --- lib/external/pattern_language | 2 +- .../content/views/view_pattern_data.hpp | 1 + .../content/views/view_pattern_data.cpp | 59 ++++- plugins/ui/CMakeLists.txt | 1 + plugins/ui/include/ui/pattern_drawer.hpp | 10 +- .../ui/include/ui/pattern_value_editor.hpp | 39 ++++ plugins/ui/source/ui/pattern_drawer.cpp | 126 +---------- plugins/ui/source/ui/pattern_value_editor.cpp | 214 ++++++++++++++++++ 8 files changed, 331 insertions(+), 121 deletions(-) create mode 100644 plugins/ui/include/ui/pattern_value_editor.hpp create mode 100644 plugins/ui/source/ui/pattern_value_editor.cpp diff --git a/lib/external/pattern_language b/lib/external/pattern_language index a3f3c1f40..44cbfa245 160000 --- a/lib/external/pattern_language +++ b/lib/external/pattern_language @@ -1 +1 @@ -Subproject commit a3f3c1f40ed4860f1c163269647c3dfd37078eb2 +Subproject commit 44cbfa2454105b714e3d71471e06f33ef5154373 diff --git a/plugins/builtin/include/content/views/view_pattern_data.hpp b/plugins/builtin/include/content/views/view_pattern_data.hpp index 547fa5f09..bf0339307 100644 --- a/plugins/builtin/include/content/views/view_pattern_data.hpp +++ b/plugins/builtin/include/content/views/view_pattern_data.hpp @@ -24,6 +24,7 @@ namespace hex::plugin::builtin { PerProvider>> m_patternDrawer; Region m_hoveredPatternRegion = Region::Invalid(); + ui::PatternValueEditor m_patternValueEditor; }; } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index 2e3260d30..23110f792 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -141,16 +141,67 @@ namespace hex::plugin::builtin { if (ImGui::BeginPopup("##PatternDataContextMenu")) { if (ImGui::MenuItemEx("hex.builtin.view.pattern_data.section.view_raw"_lang, ICON_VS_OPEN_PREVIEW)) { - const auto §ions = runtime.getSections(); - if (auto it = sections.find(selectedSection); it != sections.end()) { - const auto &[id, section] = *it; - ImHexApi::Provider::add(section.data, section.name); + if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock())) { + const auto §ions = runtime.getSections(); + if (auto it = sections.find(selectedSection); it != sections.end()) { + const auto &[id, section] = *it; + ImHexApi::Provider::add(section.data, section.name); + } } } ImGui::EndPopup(); } } + constexpr static auto SimplifiedEditorAttribute = "hex::editor_export"; + if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock()) && patternsValid) { + const auto &patterns = runtime.getPatternsWithAttribute(SimplifiedEditorAttribute); + if (!patterns.empty()) { + const auto tabName = "hex.builtin.view.pattern_data.simplified_editor"_lang; + ImGui::TabItemSpacing("##spacing", 0, ImGui::GetContentRegionAvail().x - ImGui::TabItemCalcSize(tabName, false).x); + if (ImGui::BeginTabItem(tabName, nullptr, ImGuiTabItemFlags_Trailing)) { + for (const auto &pattern : patterns) { + try { + const auto attribute = pattern->getAttributeArguments(SimplifiedEditorAttribute); + + const auto name = attribute.size() >= 1 ? attribute[0].toString() : pattern->getDisplayName(); + const auto description = attribute.size() >= 2 ? attribute[1].toString() : pattern->getComment(); + + const auto widgetPos = 200_scaled; + ImGui::TextUnformatted(name.c_str()); + ImGui::SameLine(0, 20_scaled); + if (ImGui::GetCursorPosX() < widgetPos) + ImGui::SetCursorPosX(widgetPos); + + ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, 0); + ImGui::PushItemWidth(-50_scaled); + pattern->accept(m_patternValueEditor); + ImGui::PopItemWidth(); + ImGui::PopStyleVar(); + + if (!description.empty()) { + ImGui::PushFont(nullptr, ImGui::GetFontSize() * 0.8F); + ImGui::BeginDisabled(); + ImGui::Indent(); + ImGui::TextWrapped("%s", description.c_str()); + ImGui::Unindent(); + ImGui::EndDisabled(); + ImGui::PopFont(); + } + + ImGui::Separator(); + + } catch (const std::exception &e) { + ImGui::TextUnformatted(pattern->getDisplayName().c_str()); + ImGui::TextUnformatted(e.what()); + } + } + + ImGui::EndTabItem(); + } + } + } + ImGui::EndTabBar(); } diff --git a/plugins/ui/CMakeLists.txt b/plugins/ui/CMakeLists.txt index 5d194565a..852ced507 100644 --- a/plugins/ui/CMakeLists.txt +++ b/plugins/ui/CMakeLists.txt @@ -12,6 +12,7 @@ add_imhex_plugin( source/ui/pattern_drawer.cpp source/ui/visualizer_drawer.cpp source/ui/menu_items.cpp + source/ui/pattern_value_editor.cpp INCLUDES include LIBRARIES diff --git a/plugins/ui/include/ui/pattern_drawer.hpp b/plugins/ui/include/ui/pattern_drawer.hpp index 9e45dfc97..2d6d32a33 100644 --- a/plugins/ui/include/ui/pattern_drawer.hpp +++ b/plugins/ui/include/ui/pattern_drawer.hpp @@ -8,9 +8,11 @@ #include #include +#include #include -#include + +#include struct ImGuiTableSortSpecs; @@ -20,9 +22,12 @@ namespace hex::ui { public: PatternDrawer() { m_formatters = pl::gen::fmt::createFormatters(); + m_valueEditor = PatternValueEditor([this]() { + this->resetEditing(); + }); } - virtual ~PatternDrawer() = default; + ~PatternDrawer() override = default; void draw(const std::vector> &patterns, const pl::PatternLanguage *runtime = nullptr, float height = 0.0F); @@ -111,6 +116,7 @@ namespace hex::ui { const pl::ptrn::Pattern *m_editingPattern = nullptr; u64 m_editingPatternOffset = 0; hex::ui::VisualizerDrawer m_visualizerDrawer; + hex::ui::PatternValueEditor m_valueEditor; TreeStyle m_treeStyle = TreeStyle::Default; bool m_rowColoring = false; diff --git a/plugins/ui/include/ui/pattern_value_editor.hpp b/plugins/ui/include/ui/pattern_value_editor.hpp new file mode 100644 index 000000000..b9e705a8e --- /dev/null +++ b/plugins/ui/include/ui/pattern_value_editor.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +namespace hex::ui { + + class PatternValueEditor : public pl::PatternVisitor { + public: + PatternValueEditor() = default; + explicit PatternValueEditor(const std::function& onEditCallback) : m_onEditCallback(onEditCallback) {} + + void visit(pl::ptrn::PatternArrayDynamic& pattern) override; + void visit(pl::ptrn::PatternArrayStatic& pattern) override; + void visit(pl::ptrn::PatternBitfield& pattern) override; + void visit(pl::ptrn::PatternBitfieldField& pattern) override; + void visit(pl::ptrn::PatternBitfieldArray& pattern) override; + void visit(pl::ptrn::PatternBoolean& pattern) override; + void visit(pl::ptrn::PatternCharacter& pattern) override; + void visit(pl::ptrn::PatternEnum& pattern) override; + void visit(pl::ptrn::PatternFloat& pattern) override; + void visit(pl::ptrn::PatternPadding& pattern) override; + void visit(pl::ptrn::PatternPointer& pattern) override; + void visit(pl::ptrn::PatternSigned& pattern) override; + void visit(pl::ptrn::PatternString& pattern) override; + void visit(pl::ptrn::PatternStruct& pattern) override; + void visit(pl::ptrn::PatternUnion& pattern) override; + void visit(pl::ptrn::PatternUnsigned& pattern) override; + void visit(pl::ptrn::PatternWideCharacter& pattern) override; + void visit(pl::ptrn::PatternWideString& pattern) override; + void visit(pl::ptrn::PatternError& pattern) override; + void visit(pl::ptrn::Pattern& pattern) override; + + private: + std::function m_onEditCallback = [](){}; + }; + +} diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index d8c6d4c0a..1628c3756 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -572,50 +572,7 @@ namespace hex::ui { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - auto value = pattern.getValue(); - auto valueString = pattern.toString(); - - if (const auto *enumPattern = dynamic_cast(&pattern); enumPattern != nullptr) { - if (ImGui::BeginCombo("##Enum", pattern.getFormattedValue().c_str())) { - auto currValue = pattern.getValue().toUnsigned(); - for (auto &[name, enumValue] : enumPattern->getEnumValues()) { - auto min = enumValue.min.toUnsigned(); - auto max = enumValue.max.toUnsigned(); - - bool isSelected = min <= currValue && max >= currValue; - if (ImGui::Selectable(fmt::format("{}::{}", pattern.getTypeName(), name, min, pattern.getSize() * 2).c_str(), isSelected)) { - pattern.setValue(enumValue.min); - this->resetEditing(); - } - if (isSelected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - } else if (dynamic_cast(&pattern) != nullptr) { - bool boolValue = value.toBoolean(); - if (ImGui::Checkbox("##boolean", &boolValue)) { - pattern.setValue(boolValue); - } - } else if (std::holds_alternative(value)) { - if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - wolv::math_eval::MathEvaluator mathEvaluator; - - if (auto result = mathEvaluator.evaluate(valueString); result.has_value()) - pattern.setValue(result.value()); - - this->resetEditing(); - } - } else if (std::holds_alternative(value)) { - if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - wolv::math_eval::MathEvaluator mathEvaluator; - - if (auto result = mathEvaluator.evaluate(valueString); result.has_value()) - pattern.setValue(result.value()); - - this->resetEditing(); - } - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -672,10 +629,7 @@ namespace hex::ui { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - bool value = pattern.getValue().toBoolean(); - if (ImGui::Checkbox("##boolean", &value)) { - pattern.setValue(value); - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -695,16 +649,8 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = hex::encodeByteString(pattern.getBytes()); - if (ImGui::InputText("##Character", value.data(), value.size() + 1, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - if (!value.empty()) { - auto result = hex::decodeByteString(value); - if (!result.empty()) - pattern.setValue(char(result[0])); + m_valueEditor.visit(pattern); - this->resetEditing(); - } - } ImGui::PopItemWidth(); ImGui::PopStyleVar(); } @@ -726,22 +672,7 @@ namespace hex::ui { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::BeginCombo("##Enum", pattern.getFormattedValue().c_str())) { - auto currValue = pattern.getValue().toUnsigned(); - for (auto &[name, enumValue] : pattern.getEnumValues()) { - auto min = enumValue.min.toUnsigned(); - auto max = enumValue.max.toUnsigned(); - - bool isSelected = min <= currValue && max >= currValue; - if (ImGui::Selectable(fmt::format("{}::{}", pattern.getTypeName(), name, min, pattern.getSize() * 2).c_str(), isSelected)) { - pattern.setValue(enumValue.min); - this->resetEditing(); - } - if (isSelected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -761,15 +692,7 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.toString(); - if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - wolv::math_eval::MathEvaluator mathEvaluator; - - if (auto result = mathEvaluator.evaluate(value); result.has_value()) - pattern.setValue(double(result.value())); - - this->resetEditing(); - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -815,15 +738,7 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.getFormattedValue(); - if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - wolv::math_eval::MathEvaluator mathEvaluator; - - if (auto result = mathEvaluator.evaluate(value); result.has_value()) - pattern.setValue(result.value()); - - this->resetEditing(); - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -844,11 +759,7 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.toString(); - if (ImGui::InputText("##Value", value.data(), value.size() + 1, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - pattern.setValue(value); - this->resetEditing(); - } + m_valueEditor.visit(pattern); ImGui::PopItemWidth(); ImGui::PopStyleVar(); @@ -877,11 +788,8 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.toString(); - if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - pattern.setValue(value); - this->resetEditing(); - } + m_valueEditor.visit(pattern); + ImGui::PopItemWidth(); ImGui::PopStyleVar(); } else { @@ -925,11 +833,8 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.toString(); - if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - pattern.setValue(value); - this->resetEditing(); - } + m_valueEditor.visit(pattern); + ImGui::PopItemWidth(); ImGui::PopStyleVar(); } else { @@ -966,15 +871,8 @@ namespace hex::ui { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetKeyboardFocusHere(); - auto value = pattern.toString(); - if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { - wolv::math_eval::MathEvaluator mathEvaluator; + m_valueEditor.visit(pattern); - if (auto result = mathEvaluator.evaluate(value); result.has_value()) - pattern.setValue(result.value()); - - this->resetEditing(); - } ImGui::PopItemWidth(); ImGui::PopStyleVar(); } diff --git a/plugins/ui/source/ui/pattern_value_editor.cpp b/plugins/ui/source/ui/pattern_value_editor.cpp new file mode 100644 index 000000000..6ca17ae61 --- /dev/null +++ b/plugins/ui/source/ui/pattern_value_editor.cpp @@ -0,0 +1,214 @@ +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace hex::ui { + + void PatternValueEditor::visit(pl::ptrn::PatternArrayDynamic& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternArrayStatic& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternBitfield& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternBitfieldField& pattern) { + auto value = pattern.getValue(); + auto valueString = pattern.toString(); + + if (const auto *enumPattern = dynamic_cast(&pattern); enumPattern != nullptr) { + if (ImGui::BeginCombo("##Enum", pattern.getFormattedValue().c_str())) { + auto currValue = pattern.getValue().toUnsigned(); + for (auto &[name, enumValue] : enumPattern->getEnumValues()) { + auto min = enumValue.min.toUnsigned(); + auto max = enumValue.max.toUnsigned(); + + bool isSelected = min <= currValue && max >= currValue; + if (ImGui::Selectable(fmt::format("{}::{}", pattern.getTypeName(), name, min, pattern.getSize() * 2).c_str(), isSelected)) { + pattern.setValue(enumValue.min); + m_onEditCallback(); + } + if (isSelected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } else if (dynamic_cast(&pattern) != nullptr) { + bool boolValue = value.toBoolean(); + if (ImGui::Checkbox("##boolean", &boolValue)) { + pattern.setValue(boolValue); + } + } else if (std::holds_alternative(value)) { + if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + wolv::math_eval::MathEvaluator mathEvaluator; + + if (auto result = mathEvaluator.evaluate(valueString); result.has_value()) + pattern.setValue(result.value()); + + m_onEditCallback(); + } + } else if (std::holds_alternative(value)) { + if (ImGui::InputText("##Value", valueString, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + wolv::math_eval::MathEvaluator mathEvaluator; + + if (auto result = mathEvaluator.evaluate(valueString); result.has_value()) + pattern.setValue(result.value()); + + m_onEditCallback(); + } + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternBitfieldArray& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternBoolean& pattern) { + bool value = pattern.getValue().toBoolean(); + if (ImGui::Checkbox("##boolean", &value)) { + pattern.setValue(value); + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternCharacter& pattern) { + auto value = hex::encodeByteString(pattern.getBytes()); + if (ImGui::InputText("##Character", value.data(), value.size() + 1, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + if (!value.empty()) { + auto result = hex::decodeByteString(value); + if (!result.empty()) + pattern.setValue(char(result[0])); + + m_onEditCallback(); + } + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternEnum& pattern) { + if (ImGui::BeginCombo("##Enum", pattern.getFormattedValue().c_str())) { + auto currValue = pattern.getValue().toUnsigned(); + for (auto &[name, enumValue] : pattern.getEnumValues()) { + auto min = enumValue.min.toUnsigned(); + auto max = enumValue.max.toUnsigned(); + + bool isSelected = min <= currValue && max >= currValue; + if (ImGui::Selectable(fmt::format("{}::{}", pattern.getTypeName(), name, min, pattern.getSize() * 2).c_str(), isSelected)) { + pattern.setValue(enumValue.min); + m_onEditCallback(); + } + if (isSelected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternFloat& pattern) { + auto value = pattern.toString(); + if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + wolv::math_eval::MathEvaluator mathEvaluator; + + if (auto result = mathEvaluator.evaluate(value); result.has_value()) + pattern.setValue(double(result.value())); + + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternPadding& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternPointer& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternSigned& pattern) { + auto value = pattern.getFormattedValue(); + if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + wolv::math_eval::MathEvaluator mathEvaluator; + + if (auto result = mathEvaluator.evaluate(value); result.has_value()) + pattern.setValue(result.value()); + + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternString& pattern) { + auto value = pattern.toString(); + if (ImGui::InputText("##Value", value.data(), value.size() + 1, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + pattern.setValue(value); + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternStruct& pattern) { + auto value = pattern.toString(); + if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + pattern.setValue(value); + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternUnion& pattern) { + auto value = pattern.toString(); + if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + pattern.setValue(value); + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternUnsigned& pattern) { + auto value = pattern.toString(); + if (ImGui::InputText("##Value", value, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue)) { + wolv::math_eval::MathEvaluator mathEvaluator; + + if (auto result = mathEvaluator.evaluate(value); result.has_value()) + pattern.setValue(result.value()); + + m_onEditCallback(); + } + } + + void PatternValueEditor::visit(pl::ptrn::PatternWideCharacter& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternWideString& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::PatternError& pattern) { + std::ignore = pattern; + } + + void PatternValueEditor::visit(pl::ptrn::Pattern& pattern) { + std::ignore = pattern; + } + + +} \ No newline at end of file