diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bc791408..3e642244b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,9 @@ createMagicDbList() findLibraries() +detectOS() +detectArch() + # Add bundled dependencies add_subdirectory(external/llvm) add_subdirectory(plugins/libimhex) @@ -29,9 +32,6 @@ add_subdirectory(plugins/libimhex) # Add include directories include_directories(include ${CRYPTO_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) -detectOS() -detectArch() - addVersionDefines() configurePackageCreation() diff --git a/external/ImGui/CMakeLists.txt b/external/ImGui/CMakeLists.txt index 29a92bfb1..ed5802574 100644 --- a/external/ImGui/CMakeLists.txt +++ b/external/ImGui/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(imgui source/imgui_widgets.cpp source/ImGuiFileBrowser.cpp source/TextEditor.cpp + source/imgui_imhex_extensions.cpp ) add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD) diff --git a/external/ImGui/include/imgui_imhex_extensions.h b/external/ImGui/include/imgui_imhex_extensions.h new file mode 100644 index 000000000..5ea148fa8 --- /dev/null +++ b/external/ImGui/include/imgui_imhex_extensions.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace ImGui { + + bool Hyperlink(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); + +} \ No newline at end of file diff --git a/external/ImGui/source/imgui_imhex_extensions.cpp b/external/ImGui/source/imgui_imhex_extensions.cpp new file mode 100644 index 000000000..6bef56d2d --- /dev/null +++ b/external/ImGui/source/imgui_imhex_extensions.cpp @@ -0,0 +1,44 @@ +#include + +#include +#define IMGUI_DEFINE_MATH_OPERATORS +#include +#undef IMGUI_DEFINE_MATH_OPERATORS + +namespace ImGui { + + bool Hyperlink(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) + { + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + + ImVec2 pos = window->DC.CursorPos; + ImVec2 size = CalcItemSize(size_arg, label_size.x, label_size.y); + + const ImRect bb(pos, pos + size); + if (!ItemAdd(bb, id)) + return false; + + if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) + flags |= ImGuiButtonFlags_Repeat; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + // Render + const ImColor col = (hovered && !pressed) ? ImColor(0.5F, 0.5F, 0.9F, 1.0F) : (pressed ? ImColor(0.6F, 0.6F, 1.0F, 1.0F) : ImColor(0.4F, 0.4F, 0.8F, 1.0F)); + PushStyleColor(ImGuiCol_Text, ImU32(col)); + TextEx(label, NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting + GetOverlayDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col)); + PopStyleColor(); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags); + return pressed; + } + +} \ No newline at end of file diff --git a/plugins/libimhex/include/hex/helpers/utils.hpp b/plugins/libimhex/include/hex/helpers/utils.hpp index 12c43a759..0bc35075c 100644 --- a/plugins/libimhex/include/hex/helpers/utils.hpp +++ b/plugins/libimhex/include/hex/helpers/utils.hpp @@ -76,37 +76,13 @@ namespace hex { namespace hex { - inline std::string to_string(u128 value) { - char data[45] = { 0 }; + std::string to_string(u128 value); + std::string to_string(s128 value); - u8 index = sizeof(data) - 2; - while (value != 0 && index != 0) { - data[index] = '0' + value % 10; - value /= 10; - index--; - } + std::string toByteString(u64 bytes); + std::string makePrintable(char c); - return std::string(data + index + 1); - } - - inline std::string to_string(s128 value) { - char data[45] = { 0 }; - - u128 unsignedValue = value < 0 ? -value : value; - - u8 index = sizeof(data) - 2; - while (unsignedValue != 0 && index != 0) { - data[index] = '0' + unsignedValue % 10; - unsignedValue /= 10; - index--; - } - - if (value < 0) { - data[index] = '-'; - return std::string(data + index); - } else - return std::string(data + index + 1); - } + void openWebpage(std::string_view url); template inline std::string format(const char *format, Args ... args) { @@ -116,7 +92,7 @@ namespace hex { return ""; std::vector buffer(size + 1, 0x00); - if (snprintf(buffer.data(), size, format, args ...) <= 0) + if (snprintf(buffer.data(), size + 1, format, args ...) <= 0) return ""; @@ -124,7 +100,9 @@ namespace hex { } [[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const hex::unsigned_integral auto &value) { - std::remove_cvref_t mask = (std::numeric_limits>::max() >> (((sizeof(value) * 8) - 1) - (from - to))) << to; + using ValueType = std::remove_cvref_t; + ValueType mask = (std::numeric_limits::max() >> (((sizeof(value) * 8) - 1) - (from - to))) << to; + return (value & mask) >> to; } @@ -134,9 +112,6 @@ namespace hex { return (((value ^ mask) - mask) << ((sizeof(T) * 8) - targetWidth)) >> ((sizeof(T) * 8) - targetWidth); } - std::string toByteString(u64 bytes); - std::string makePrintable(char c); - template struct always_false : std::false_type {}; @@ -191,38 +166,9 @@ namespace hex { return T(1) << bit_width(T(x - 1)); } - inline std::vector splitString(std::string_view string, std::string_view delimiter) { - size_t start = 0, end; - std::string token; - std::vector res; + std::vector splitString(std::string_view string, std::string_view delimiter); - while ((end = string.find (delimiter, start)) != std::string::npos) { - token = string.substr(start, end - start); - start = end + delimiter.length(); - res.push_back(token); - } - - res.push_back(std::string(string.substr(start))); - return res; - } - - inline std::string toEngineeringString(double value) { - constexpr std::array prefixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" }; - - int8_t prefixIndex = 6; - - while (prefixIndex != 0 && prefixIndex != 12 && (value >= 1000 || value < 1) && value != 0) { - if (value >= 1000) { - value /= 1000; - prefixIndex++; - } else if (value < 1) { - value *= 1000; - prefixIndex--; - } - } - - return std::to_string(value).substr(0, 5) + prefixes[prefixIndex]; - } + std::string toEngineeringString(double value); std::vector readFile(std::string_view path); diff --git a/plugins/libimhex/source/helpers/utils.cpp b/plugins/libimhex/source/helpers/utils.cpp index 676d09b03..6fef2c202 100644 --- a/plugins/libimhex/source/helpers/utils.cpp +++ b/plugins/libimhex/source/helpers/utils.cpp @@ -6,6 +6,38 @@ namespace hex { + std::string to_string(u128 value) { + char data[45] = { 0 }; + + u8 index = sizeof(data) - 2; + while (value != 0 && index != 0) { + data[index] = '0' + value % 10; + value /= 10; + index--; + } + + return std::string(data + index + 1); + } + + std::string to_string(s128 value) { + char data[45] = { 0 }; + + u128 unsignedValue = value < 0 ? -value : value; + + u8 index = sizeof(data) - 2; + while (unsignedValue != 0 && index != 0) { + data[index] = '0' + unsignedValue % 10; + unsignedValue /= 10; + index--; + } + + if (value < 0) { + data[index] = '-'; + return std::string(data + index); + } else + return std::string(data + index + 1); + } + std::string toByteString(u64 bytes) { double value = bytes; u8 unitIndex = 0; @@ -74,6 +106,39 @@ namespace hex { } } + std::vector splitString(std::string_view string, std::string_view delimiter) { + size_t start = 0, end; + std::string token; + std::vector res; + + while ((end = string.find (delimiter, start)) != std::string::npos) { + token = string.substr(start, end - start); + start = end + delimiter.length(); + res.push_back(token); + } + + res.push_back(std::string(string.substr(start))); + return res; + } + + std::string toEngineeringString(double value) { + constexpr std::array prefixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" }; + + int8_t prefixIndex = 6; + + while (prefixIndex != 0 && prefixIndex != 12 && (value >= 1000 || value < 1) && value != 0) { + if (value >= 1000) { + value /= 1000; + prefixIndex++; + } else if (value < 1) { + value *= 1000; + prefixIndex--; + } + } + + return std::to_string(value).substr(0, 5) + prefixes[prefixIndex]; + } + std::vector readFile(std::string_view path) { FILE *file = fopen(path.data(), "rb"); @@ -90,4 +155,18 @@ namespace hex { return result; } + void openWebpage(std::string_view url) { + + #if defined(OS_WINDOWS) + system(hex::format("start %s", url.data()).c_str()); + #elif defined(OS_MACOS) + system(hex::format("open %s", url.data()).c_str()) + #elif defined(OS_LINUX) + system(hex::format("xdg-open %s", url.data()).c_str()) + #else + #warning "Unknown OS, can't open webpages" + #endif + + } + } \ No newline at end of file diff --git a/source/views/view_help.cpp b/source/views/view_help.cpp index be06f78f5..2a1f35480 100644 --- a/source/views/view_help.cpp +++ b/source/views/view_help.cpp @@ -1,5 +1,7 @@ #include "views/view_help.hpp" +#include + namespace hex { ViewHelp::ViewHelp() : View("Help") { @@ -31,13 +33,15 @@ namespace hex { if (ImGui::BeginPopupModal("About", &this->m_aboutWindowOpen, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("ImHex Hex Editor v%s by WerWolv -", IMHEX_VERSION); #if defined(GIT_BRANCH) && defined(GIT_COMMIT_HASH) - ImGui::SameLine(); - ImGui::TextColored(ImVec4(0.4F, 0.8F, 0.4F, 1.0F), "%s@%s", GIT_BRANCH, GIT_COMMIT_HASH); + ImGui::SameLine(); + if (ImGui::Hyperlink(hex::format("%s@%s", GIT_BRANCH, GIT_COMMIT_HASH).c_str())) + hex::openWebpage("https://github.com/WerWolv/ImHex/commit/" GIT_COMMIT_HASH); #endif ImGui::TextUnformatted("Source code available on GitHub:"); ImGui::SameLine(); - ImGui::TextColored(ImVec4(0.4F, 0.4F, 0.8F, 1.0F), "WerWolv/ImHex "); + if (ImGui::Hyperlink("WerWolv/ImHex")) + hex::openWebpage("https://github.com/WerWolv/ImHex"); ImGui::NewLine(); ImGui::Text("Donations"); @@ -50,10 +54,8 @@ namespace hex { ImGui::NewLine(); for (auto &link : Links) { - ImGui::TextColored(ImVec4(0.4F, 0.4F, 0.8F, 1.0F), link); ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::CalcTextSize(" Copy ").x); - if (ImGui::Button((std::string("Copy##") + link).c_str())) - ImGui::SetClipboardText(link); + if (ImGui::Hyperlink(link)) + hex::openWebpage(link); } ImGui::NewLine();