Skip to content

Commit

Permalink
feat: Added a preview to the Edit -> Copy as options
Browse files Browse the repository at this point in the history
Closes #2026
  • Loading branch information
WerWolv committed Dec 30, 2024
1 parent dab3f72 commit 0ae8237
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib/libimhex/include/hex/api/content_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ namespace hex {

namespace impl {

using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size)>;
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size, bool preview)>;
struct ExportMenuEntry {
UnlocalizedString unlocalizedName;
Callback callback;
Expand Down
1 change: 1 addition & 0 deletions plugins/builtin/romfs/lang/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@
"hex.builtin.view.hex_editor.goto.offset.relative": "Relative",
"hex.builtin.view.hex_editor.menu.edit.copy": "Copy",
"hex.builtin.view.hex_editor.menu.edit.copy_as": "Copy as",
"hex.builtin.view.hex_editor.menu.edit.copy_as.preview": "Copy Preview",
"hex.builtin.view.hex_editor.menu.edit.cut": "Cut",
"hex.builtin.view.hex_editor.menu.edit.fill": "Fill...",
"hex.builtin.view.hex_editor.menu.edit.insert": "Insert...",
Expand Down
40 changes: 23 additions & 17 deletions plugins/builtin/source/content/data_formatters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,57 +54,59 @@ namespace hex::plugin::builtin {

void registerDataFormatters() {

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.c", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.c", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, hex::format("const uint8_t data[{0}] = {{", size), "0x{0:02X}, ", "};");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.cpp", [](prv::Provider *provider, u64 offset, size_t size) {
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.copy_as.name");
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.cpp", [](prv::Provider *provider, u64 offset, size_t size, bool preview) {
if (!preview) {
AchievementManager::unlockAchievement("hex.builtin.achievement.hex_editor", "hex.builtin.achievement.hex_editor.copy_as.name");
}

return formatLanguageArray(provider, offset, size, hex::format("constexpr std::array<uint8_t, {0}> data = {{", size), "0x{0:02X}, ", "};");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.java", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.java", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "final byte[] data = {", "0x{0:02X}, ", "};");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.csharp", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.csharp", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "const byte[] data = {", "0x{0:02X}, ", "};");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.rust", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.rust", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, hex::format("let data: [u8; 0x{0:02X}] = [", size), "0x{0:02X}, ", "];");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.python", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.python", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "data = bytes([", "0x{0:02X}, ", "])");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.js", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.js", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "const data = new Uint8Array([", "0x{0:02X}, ", "]);");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.lua", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.lua", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "data = {", "0x{0:02X}, ", "}");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.go", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.go", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "data := [...]byte{", "0x{0:02X}, ", "}", false);
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.crystal", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.crystal", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "data = [", "0x{0:02X}, ", "] of UInt8");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.swift", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.swift", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "let data: [Uint8] = [", "0x{0:02X}, ", "]");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.pascal", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.pascal", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, hex::format("data: array[0..{0}] of Byte = (", size - 1), "${0:02X}, ", ")");
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.base64", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.base64", [](prv::Provider *provider, u64 offset, size_t size, bool) {
std::vector<u8> data(size, 0x00);
provider->read(offset, data.data(), size);

Expand All @@ -113,11 +115,15 @@ namespace hex::plugin::builtin {
return std::string(result.begin(), result.end());
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.hex_view", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.hex_view", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return hex::generateHexView(offset, size, provider);
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.html", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.html", [](prv::Provider *provider, u64 offset, size_t size, bool preview) {
// Don't display a preview for this formatter as it wouldn't make much sense either way.
if (preview)
return std::string();

std::string result =
"<div>\n"
" <style type=\"text/css\">\n"
Expand Down Expand Up @@ -180,7 +186,7 @@ namespace hex::plugin::builtin {
return result;
});

ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.escaped_string", [](prv::Provider *provider, u64 offset, size_t size) {
ContentRegistry::DataFormatter::addExportMenuEntry("hex.builtin.view.hex_editor.copy.escaped_string", [](prv::Provider *provider, u64 offset, size_t size, bool) {
return formatLanguageArray(provider, offset, size, "\"", "\\x{0:02X}", "\"", false, false);
});

Expand Down
2 changes: 1 addition & 1 deletion plugins/builtin/source/content/main_menu_items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ namespace hex::plugin::builtin {
provider
});

auto result = formatter.callback(provider, selection.getStartAddress(), selection.getSize());
auto result = formatter.callback(provider, selection.getStartAddress(), selection.getSize(), false);

wolv::io::File file(path, wolv::io::File::Mode::Create);
if (!file.isValid()) {
Expand Down
20 changes: 19 additions & 1 deletion plugins/builtin/source/content/views/view_hex_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,10 +1269,28 @@ namespace hex::plugin::builtin {
callback(
provider,
selection->getStartAddress(),
selection->size
selection->size,
false
).c_str()
);
}

if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
const auto previewText = callback(
provider,
selection->getStartAddress(),
std::min<u64>(selection->size, 32),
true
);

if (!previewText.empty()) {
if (ImGui::BeginTooltip()) {
ImGuiExt::Header("hex.builtin.view.hex_editor.menu.edit.copy_as.preview"_lang, true);
ImGui::TextDisabled("%s", previewText.c_str());
ImGui::EndTooltip();
}
}
}
}
},
[] {
Expand Down

0 comments on commit 0ae8237

Please sign in to comment.