feat: Added context menu and next/previous buttons to the data inspector
This commit is contained in:
parent
f0525d6463
commit
cb09cf3734
@ -24,6 +24,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::DataInspector::impl::DisplayFunction displayFunction;
|
||||
std::optional<ContentRegistry::DataInspector::impl::EditingFunction> editingFunction;
|
||||
bool editing;
|
||||
u64 requiredSize;
|
||||
|
||||
std::string filterValue;
|
||||
};
|
||||
@ -62,6 +63,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
pl::PatternLanguage m_runtime;
|
||||
std::vector<InspectorCacheEntry> m_cachedData, m_workData;
|
||||
std::optional<UnlocalizedString> m_selectedEntryName;
|
||||
|
||||
TaskHolder m_updateTask;
|
||||
|
||||
|
@ -717,6 +717,8 @@
|
||||
"hex.builtin.view.constants.row.desc": "Description",
|
||||
"hex.builtin.view.constants.row.name": "Name",
|
||||
"hex.builtin.view.constants.row.value": "Value",
|
||||
"hex.builtin.view.data_inspector.menu.copy": "Copy Value",
|
||||
"hex.builtin.view.data_inspector.menu.edit": "Edit Value",
|
||||
"hex.builtin.view.data_inspector.execution_error": "Custom row evaluation error",
|
||||
"hex.builtin.view.data_inspector.invert": "Invert",
|
||||
"hex.builtin.view.data_inspector.name": "Data Inspector",
|
||||
|
@ -91,6 +91,7 @@ namespace hex::plugin::builtin {
|
||||
entry.generatorFunction(buffer, m_endian, m_numberDisplayStyle),
|
||||
entry.editingFunction,
|
||||
false,
|
||||
entry.requiredSize,
|
||||
entry.unlocalizedName
|
||||
);
|
||||
}
|
||||
@ -160,12 +161,13 @@ namespace hex::plugin::builtin {
|
||||
|
||||
auto displayFunction = createPatternErrorDisplayFunction();
|
||||
|
||||
// Insert the inspector into the list
|
||||
// Insert the inspector containing the error message into the list
|
||||
m_workData.emplace_back(
|
||||
wolv::util::toUTF8String(path.filename()),
|
||||
std::move(displayFunction),
|
||||
std::nullopt,
|
||||
false,
|
||||
0,
|
||||
wolv::util::toUTF8String(path)
|
||||
);
|
||||
|
||||
@ -215,6 +217,7 @@ namespace hex::plugin::builtin {
|
||||
displayFunction,
|
||||
editingFunction,
|
||||
false,
|
||||
pattern->getSize(),
|
||||
wolv::util::toUTF8String(path) + ":" + pattern->getVariableName()
|
||||
);
|
||||
|
||||
@ -223,12 +226,13 @@ namespace hex::plugin::builtin {
|
||||
} catch (const pl::core::err::EvaluatorError::Exception &) {
|
||||
auto displayFunction = createPatternErrorDisplayFunction();
|
||||
|
||||
// Insert the inspector into the list
|
||||
// Insert the inspector containing the error message into the list
|
||||
m_workData.emplace_back(
|
||||
wolv::util::toUTF8String(path.filename()),
|
||||
std::move(displayFunction),
|
||||
std::nullopt,
|
||||
false,
|
||||
0,
|
||||
wolv::util::toUTF8String(path)
|
||||
);
|
||||
}
|
||||
@ -260,6 +264,36 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
}
|
||||
|
||||
const auto selection = ImHexApi::HexEditor::getSelection();
|
||||
const auto selectedEntryIt = std::find_if(m_cachedData.begin(), m_cachedData.end(), [this](const InspectorCacheEntry &entry) {
|
||||
return entry.unlocalizedName == m_selectedEntryName;
|
||||
});
|
||||
|
||||
u64 requiredSize = selectedEntryIt == m_cachedData.end() ? 0x00 : selectedEntryIt->requiredSize;
|
||||
|
||||
ImGui::BeginDisabled(!selection.has_value() || !m_selectedEntryName.has_value());
|
||||
{
|
||||
const auto buttonSize = ImVec2((ImGui::GetContentRegionAvail().x / 2) - ImGui::GetStyle().FramePadding.x, 0);
|
||||
const auto baseAddress = m_selectedProvider->getBaseAddress();
|
||||
const auto providerSize = m_selectedProvider->getActualSize();
|
||||
const auto providerEndAddress = baseAddress + providerSize;
|
||||
|
||||
ImGui::BeginDisabled(providerSize < requiredSize || selection->getStartAddress() < baseAddress + requiredSize);
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_ARROW_LEFT, ImGui::GetStyleColorVec4(ImGuiCol_Text), buttonSize)) {
|
||||
ImHexApi::HexEditor::setSelection(Region { selection->getStartAddress() - requiredSize, requiredSize });
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(providerSize < requiredSize || selection->getEndAddress() > providerEndAddress - requiredSize);
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_ARROW_RIGHT, ImGui::GetStyleColorVec4(ImGuiCol_Text), buttonSize)) {
|
||||
ImHexApi::HexEditor::setSelection(Region { selection->getStartAddress() + requiredSize, requiredSize });
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (ImGui::BeginTable("##datainspector", m_tableEditingModeEnabled ? 3 : 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg,
|
||||
ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) {
|
||||
@ -379,16 +413,36 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SameLine();
|
||||
|
||||
// Handle copying the value to the clipboard when clicking the row
|
||||
if (ImGui::Selectable("##InspectorLine", false, ImGuiSelectableFlags_SpanAllColumns |
|
||||
ImGuiSelectableFlags_AllowOverlap)) {
|
||||
ImGui::SetClipboardText(copyValue.c_str());
|
||||
if (ImGui::Selectable("##InspectorLine", m_selectedEntryName == entry.unlocalizedName, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap)) {
|
||||
m_selectedEntryName = entry.unlocalizedName;
|
||||
if (auto selection = ImHexApi::HexEditor::getSelection(); selection.has_value()) {
|
||||
ImHexApi::HexEditor::setSelection(Region { selection->getStartAddress(), entry.requiredSize });
|
||||
}
|
||||
}
|
||||
|
||||
// Enter editing mode when double-clicking the row
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) &&
|
||||
entry.editingFunction.has_value() && m_selectedProvider->isWritable()) {
|
||||
entry.editing = true;
|
||||
m_editingValue = copyValue;
|
||||
const bool editable = entry.editingFunction.has_value() && m_selectedProvider->isWritable();
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && editable) {
|
||||
entry.editing = true;
|
||||
m_editingValue = copyValue;
|
||||
m_selectedEntryName.reset();
|
||||
}
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
|
||||
ImGui::OpenPopup("##InspectorMenu");
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("##InspectorMenu")) {
|
||||
if (ImGui::MenuItemEx("hex.builtin.view.data_inspector.menu.copy"_lang, ICON_VS_COPY)) {
|
||||
ImGui::SetClipboardText(copyValue.c_str());
|
||||
}
|
||||
if (ImGui::MenuItemEx("hex.builtin.view.data_inspector.menu.edit"_lang, ICON_VS_EDIT, nullptr, false, editable)) {
|
||||
entry.editing = true;
|
||||
m_editingValue = copyValue;
|
||||
m_selectedEntryName.reset();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user