1
0
mirror of synced 2025-01-26 16:23:44 +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 */ /* Data Inspector Registry. Allows adding of new types to the data inspector */
namespace DataInspector { namespace DataInspector {
enum class NumberDisplayStyle enum class NumberDisplayStyle : u8 {
{
Decimal, Decimal,
Hexadecimal, Hexadecimal,
Octal Octal
@ -677,6 +676,13 @@ namespace hex {
std::optional<impl::EditingFunction> editingFunction = std::nullopt 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 */ /* 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) }); 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 { namespace ContentRegistry::DataProcessorNode {

View File

@ -91,6 +91,7 @@
"hex.builtin.inspector.i48": "int48_t", "hex.builtin.inspector.i48": "int48_t",
"hex.builtin.inspector.i64": "int64_t", "hex.builtin.inspector.i64": "int64_t",
"hex.builtin.inspector.i8": "int8_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.long_double": "long double (128 bit)",
"hex.builtin.inspector.rgb565": "RGB565 Color", "hex.builtin.inspector.rgb565": "RGB565 Color",
"hex.builtin.inspector.rgba8": "RGBA8 Color", "hex.builtin.inspector.rgba8": "RGBA8 Color",

View File

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <fonts/vscode_icons.hpp>
#include <hex/ui/imgui_imhex_extensions.h> #include <hex/ui/imgui_imhex_extensions.h>
namespace hex::plugin::builtin { namespace hex::plugin::builtin {
@ -77,48 +78,60 @@ namespace hex::plugin::builtin {
return {}; return {};
} }
template<std::integral T, size_t Size = sizeof(T)> template<std::unsigned_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)) { static T bufferToInteger(const std::vector<u8> &buffer, std::endian endian) {
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; T value = 0x00;
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size)); 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)> 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) if (buffer.size() < Size)
return { }; 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)); 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; return hex::format(format, bufferToInteger<T, Size>(buffer, endian));
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);
} }
template<std::integral T, size_t Size = sizeof(T)> 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)) { 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>) if constexpr (std::integral<T>)
return unsignedToString<T, Size>(buffer, endian, style); return bufferToIntegerString<T, Size>(buffer, endian, style);
else if constexpr (std::signed_integral<T>)
return signedToString<T, Size>(buffer, endian, style);
else else
return {}; return {};
} }
template<typename T> template<typename T, size_t Size = sizeof(T), typename Func = void>
static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(T func) { static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(Func func) {
return [func](const std::vector<u8> &buffer, std::endian endian, Style style) { 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), ContentRegistry::DataInspector::add("hex.builtin.inspector.u8", sizeof(u8),
drawString(integerToString<u8>), drawString<u8>(integerToString<u8>),
stringToInteger<u8> stringToInteger<u8>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i8", sizeof(i8), ContentRegistry::DataInspector::add("hex.builtin.inspector.i8", sizeof(i8),
drawString(integerToString<i8>), drawString<i8>(integerToString<i8>),
stringToInteger<i8> stringToInteger<i8>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.u16", sizeof(u16), ContentRegistry::DataInspector::add("hex.builtin.inspector.u16", sizeof(u16),
drawString(integerToString<u16>), drawString<u16>(integerToString<u16>),
stringToInteger<u16> stringToInteger<u16>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i16", sizeof(i16), ContentRegistry::DataInspector::add("hex.builtin.inspector.i16", sizeof(i16),
drawString(integerToString<i16>), drawString<i16>(integerToString<i16>),
stringToInteger<i16> stringToInteger<i16>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.u24", 3, ContentRegistry::DataInspector::add("hex.builtin.inspector.u24", 3,
drawString(integerToString<u32, 3>), drawString<u32, 3>(integerToString<u32, 3>),
stringToInteger<u32, 3> stringToInteger<u32, 3>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i24", 3, ContentRegistry::DataInspector::add("hex.builtin.inspector.i24", 3,
drawString(integerToString<i32, 3>), drawString<i32, 3>(integerToString<i32, 3>),
stringToInteger<i32, 3> stringToInteger<i32, 3>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.u32", sizeof(u32), ContentRegistry::DataInspector::add("hex.builtin.inspector.u32", sizeof(u32),
drawString(integerToString<u32>), drawString<u32>(integerToString<u32>),
stringToInteger<u32> stringToInteger<u32>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i32", sizeof(i32), ContentRegistry::DataInspector::add("hex.builtin.inspector.i32", sizeof(i32),
drawString(integerToString<i32>), drawString<i32>(integerToString<i32>),
stringToInteger<i32> stringToInteger<i32>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.u48", 6, ContentRegistry::DataInspector::add("hex.builtin.inspector.u48", 6,
drawString(integerToString<u64, 6>), drawString<u64, 6>(integerToString<u64, 6>),
stringToInteger<u64, 6> stringToInteger<u64, 6>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i48", 6, ContentRegistry::DataInspector::add("hex.builtin.inspector.i48", 6,
drawString(integerToString<i64, 6>), drawString<i64, 6>(integerToString<i64, 6>),
stringToInteger<i64, 6> stringToInteger<i64, 6>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.u64", sizeof(u64), ContentRegistry::DataInspector::add("hex.builtin.inspector.u64", sizeof(u64),
drawString(integerToString<u64>), drawString<u64>(integerToString<u64>),
stringToInteger<u64> stringToInteger<u64>
); );
ContentRegistry::DataInspector::add("hex.builtin.inspector.i64", sizeof(i64), ContentRegistry::DataInspector::add("hex.builtin.inspector.i64", sizeof(i64),
drawString(integerToString<i64>), drawString<i64>(integerToString<i64>),
stringToInteger<i64> stringToInteger<i64>
); );

View File

@ -429,11 +429,11 @@ namespace hex::plugin::builtin {
m_selectedEntryName.reset(); m_selectedEntryName.reset();
} }
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) { 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)) { if (ImGui::MenuItemEx("hex.builtin.view.data_inspector.menu.copy"_lang, ICON_VS_COPY)) {
ImGui::SetClipboardText(copyValue.c_str()); ImGui::SetClipboardText(copyValue.c_str());
} }