1
0
mirror of synced 2025-01-25 15:53:43 +01:00

feat: Added "Jump to address" option to data inspector row context menu

This commit is contained in:
WerWolv 2024-12-30 22:32:06 +01:00
parent 0dc1af0747
commit dab3f722e8
5 changed files with 68 additions and 40 deletions

View File

@ -622,8 +622,7 @@ namespace hex {
/* Data Inspector Registry. Allows adding of new types to the data inspector */
namespace DataInspector {
enum class NumberDisplayStyle
{
enum class NumberDisplayStyle : u8 {
Decimal,
Hexadecimal,
Octal
@ -677,6 +676,13 @@ namespace hex {
std::optional<impl::EditingFunction> editingFunction = std::nullopt
);
/**
* @brief Allows adding new menu items to data inspector row context menus. Call this function inside the
* draw function of the data inspector row definition.
* @param function Callback that will draw menu items
*/
void drawMenuItems(const std::function<void()> &function);
}
/* Data Processor Node Registry. Allows adding new processor nodes to be used in the data processor */

View File

@ -760,6 +760,14 @@ namespace hex {
impl::s_entries->push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
}
void drawMenuItems(const std::function<void()> &function) {
if (ImGui::BeginPopup("##DataInspectorRowContextMenu")) {
function();
ImGui::Separator();
ImGui::EndPopup();
}
}
}
namespace ContentRegistry::DataProcessorNode {

View File

@ -91,6 +91,7 @@
"hex.builtin.inspector.i48": "int48_t",
"hex.builtin.inspector.i64": "int64_t",
"hex.builtin.inspector.i8": "int8_t",
"hex.builtin.inspector.jump_to_address": "Jump to address",
"hex.builtin.inspector.long_double": "long double (128 bit)",
"hex.builtin.inspector.rgb565": "RGB565 Color",
"hex.builtin.inspector.rgba8": "RGBA8 Color",

View File

@ -13,6 +13,7 @@
#include <string>
#include <imgui_internal.h>
#include <fonts/vscode_icons.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin {
@ -77,48 +78,60 @@ namespace hex::plugin::builtin {
return {};
}
template<std::integral T, size_t Size = sizeof(T)>
static std::string unsignedToString(const std::vector<u8> &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) {
if (buffer.size() < Size)
return { };
auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? hex::format("0x{{0:0{}X}}", Size * 2) : hex::format("0o{{0:0{}o}}", Size * 3));
template<std::unsigned_integral T, size_t Size = sizeof(T)>
static T bufferToInteger(const std::vector<u8> &buffer, std::endian endian) {
T value = 0x00;
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
return hex::format(format, hex::changeEndianness(value, Size, endian));
return hex::changeEndianness(value, Size, endian);
}
template<std::signed_integral T, size_t Size = sizeof(T)>
static T bufferToInteger(const std::vector<u8> &buffer, std::endian endian) {
T value = 0x00;
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
value = hex::changeEndianness(value, Size, endian);
if (Size != sizeof(T))
value = hex::signExtend(Size * 8, value);
return value;
}
template<std::integral T, size_t Size = sizeof(T)>
static std::string signedToString(const std::vector<u8> &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) {
static std::string bufferToIntegerString(const std::vector<u8> &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) {
if (buffer.size() < Size)
return { };
auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? hex::format("0x{{0:0{}X}}", Size * 2) : hex::format("0o{{0:0{}o}}", Size * 3));
T value = 0x00;
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
auto number = hex::changeEndianness(value, Size, endian);
if (Size != sizeof(T))
number = hex::signExtend(Size * 8, number);
return hex::format(format, number);
return hex::format(format, bufferToInteger<T, Size>(buffer, endian));
}
template<std::integral T, size_t Size = sizeof(T)>
static std::string integerToString(const std::vector<u8> &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) {
if constexpr (std::unsigned_integral<T>)
return unsignedToString<T, Size>(buffer, endian, style);
else if constexpr (std::signed_integral<T>)
return signedToString<T, Size>(buffer, endian, style);
if constexpr (std::integral<T>)
return bufferToIntegerString<T, Size>(buffer, endian, style);
else
return {};
}
template<typename T>
static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(T func) {
template<typename T, size_t Size = sizeof(T), typename Func = void>
static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(Func func) {
return [func](const std::vector<u8> &buffer, std::endian endian, Style style) {
return [value = func(buffer, endian, style)]() -> std::string { ImGui::TextUnformatted(value.c_str()); return value; };
return [buffer, endian, value = func(buffer, endian, style)]() -> std::string {
ContentRegistry::DataInspector::drawMenuItems([&] {
if (ImGui::MenuItemEx("hex.builtin.inspector.jump_to_address"_lang, ICON_VS_DEBUG_STEP_OUT)) {
auto address = bufferToInteger<T, Size>(buffer, endian);
if (address >= 0) {
ImHexApi::HexEditor::setSelection(Region { u64(address), sizeof(u8) });
}
}
});
ImGui::TextUnformatted(value.c_str());
return value;
};
};
}
@ -156,62 +169,62 @@ namespace hex::plugin::builtin {
ContentRegistry::DataInspector::add("hex.builtin.inspector.u8", sizeof(u8),
drawString(integerToString<u8>),
drawString<u8>(integerToString<u8>),
stringToInteger<u8>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i8", sizeof(i8),
drawString(integerToString<i8>),
stringToInteger<i8>
drawString<i8>(integerToString<i8>),
stringToInteger<i8>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.u16", sizeof(u16),
drawString(integerToString<u16>),
drawString<u16>(integerToString<u16>),
stringToInteger<u16>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i16", sizeof(i16),
drawString(integerToString<i16>),
drawString<i16>(integerToString<i16>),
stringToInteger<i16>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.u24", 3,
drawString(integerToString<u32, 3>),
drawString<u32, 3>(integerToString<u32, 3>),
stringToInteger<u32, 3>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i24", 3,
drawString(integerToString<i32, 3>),
drawString<i32, 3>(integerToString<i32, 3>),
stringToInteger<i32, 3>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.u32", sizeof(u32),
drawString(integerToString<u32>),
drawString<u32>(integerToString<u32>),
stringToInteger<u32>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i32", sizeof(i32),
drawString(integerToString<i32>),
drawString<i32>(integerToString<i32>),
stringToInteger<i32>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.u48", 6,
drawString(integerToString<u64, 6>),
drawString<u64, 6>(integerToString<u64, 6>),
stringToInteger<u64, 6>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i48", 6,
drawString(integerToString<i64, 6>),
drawString<i64, 6>(integerToString<i64, 6>),
stringToInteger<i64, 6>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.u64", sizeof(u64),
drawString(integerToString<u64>),
drawString<u64>(integerToString<u64>),
stringToInteger<u64>
);
ContentRegistry::DataInspector::add("hex.builtin.inspector.i64", sizeof(i64),
drawString(integerToString<i64>),
drawString<i64>(integerToString<i64>),
stringToInteger<i64>
);

View File

@ -429,11 +429,11 @@ namespace hex::plugin::builtin {
m_selectedEntryName.reset();
}
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
ImGui::OpenPopup("##InspectorMenu");
ImGui::OpenPopup("##DataInspectorRowContextMenu");
}
}
if (ImGui::BeginPopup("##InspectorMenu")) {
if (ImGui::BeginPopup("##DataInspectorRowContextMenu")) {
if (ImGui::MenuItemEx("hex.builtin.view.data_inspector.menu.copy"_lang, ICON_VS_COPY)) {
ImGui::SetClipboardText(copyValue.c_str());
}