1
0
mirror of synced 2024-12-14 08:42:54 +01:00
ImHex/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h

337 lines
13 KiB
C
Raw Normal View History

#pragma once
#include <hex.hpp>
2023-08-26 23:43:35 +02:00
#include <cstddef>
#include <string>
2023-08-26 23:43:35 +02:00
#include <span>
2021-01-27 12:04:42 +01:00
#include <imgui.h>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/concepts.hpp>
#include <hex/helpers/fs.hpp>
2021-08-21 00:51:50 +02:00
#include <wolv/utils/string.hpp>
2021-08-21 00:51:50 +02:00
enum ImGuiCustomCol {
ImGuiCustomCol_DescButton,
ImGuiCustomCol_DescButtonHovered,
ImGuiCustomCol_DescButtonActive,
ImGuiCustomCol_ToolbarGray,
ImGuiCustomCol_ToolbarRed,
ImGuiCustomCol_ToolbarYellow,
ImGuiCustomCol_ToolbarGreen,
ImGuiCustomCol_ToolbarBlue,
ImGuiCustomCol_ToolbarPurple,
ImGuiCustomCol_ToolbarBrown,
ImGuiCustomCol_LoggerDebug,
ImGuiCustomCol_LoggerInfo,
ImGuiCustomCol_LoggerWarning,
ImGuiCustomCol_LoggerError,
ImGuiCustomCol_LoggerFatal,
ImGuiCustomCol_AchievementUnlocked,
ImGuiCustomCol_FindHighlight,
ImGuiCustomCol_DiffAdded,
ImGuiCustomCol_DiffRemoved,
ImGuiCustomCol_DiffChanged,
ImGuiCustomCol_AdvancedEncodingASCII,
ImGuiCustomCol_AdvancedEncodingSingleChar,
ImGuiCustomCol_AdvancedEncodingMultiChar,
ImGuiCustomCol_AdvancedEncodingUnknown,
ImGuiCustomCol_Highlight,
ImGuiCustomCol_Patches,
ImGuiCustomCol_PatternSelected,
feat: Greatly improved the IEEE754 tool (#1047) I just realized one feature request existed about this tool and have added a comment to it referring this pr. Errors and additions are described in the fork commit already. I'm not sure if I should repeat them here again. I have tested the changes thoroughly, but it is always possible some fringe case was not tested and is incorrect. The tests were done using the many similar online calculators for IEEE 754 floating point formats. IEEE 745 floating point tool redesign modeled after 'float toy' web app (http://evanw.github.io/float-toy/) Streamlined output using colors and compact layout which can be further simplified. Chosen display mode (detailed or simplified) is automatically saved and set on new sessions. Edit the binary bits, the integer hexadecimal or the floating point decimal values and the entire app will update with the change. Supports the main IEEE745 standard formats (half, single and double precision) together with custom formats of size <= 64 bits. Each format choice uses and displays the number of significant decimal digits defined by the mantissa size. Added labels to identify the location of each bit box inside the binary representation. Satisfies round trip / idempotent (reproducing) conversion property Added theme colors, radio buttons for display mode and a clear button that resets the tool. Removed previously and incorrectly added locale translation to various labels and languages Attempted to adhere to code style formatting using existing code as example. An effort was made to use preferred variable types and functions from std namespace when appropriate. Attempted to document code using comments. Not implemented / left to complete at an later time Arbitrary width and precision formats. Extended precision formats. Shortest string property. hexadecimal floating point display and conversions.
2023-05-19 21:18:38 +02:00
ImGuiCustomCol_IEEEToolSign,
ImGuiCustomCol_IEEEToolExp,
ImGuiCustomCol_IEEEToolMantissa,
2023-05-23 13:20:18 +02:00
ImGuiCustomCol_BlurBackground,
2021-08-21 00:51:50 +02:00
ImGuiCustomCol_COUNT
};
enum ImGuiCustomStyle {
ImGuiCustomStyle_WindowBlur,
ImGuiCustomStyle_COUNT
};
namespace ImGuiExt {
class Texture {
public:
enum class Filter {
Linear,
Nearest
};
Texture() = default;
Texture(const ImU8 *buffer, int size, Filter filter = Filter::Nearest, int width = 0, int height = 0);
Texture(std::span<const std::byte> bytes, Filter filter = Filter::Nearest, int width = 0, int height = 0);
explicit Texture(const char *path, Filter filter = Filter::Nearest);
explicit Texture(const std::fs::path &path, Filter filter = Filter::Nearest);
Texture(unsigned int texture, int width, int height);
Texture(const Texture&) = delete;
Texture(Texture&& other) noexcept;
2021-08-18 22:36:46 +02:00
~Texture();
Texture& operator=(const Texture&) = delete;
Texture& operator=(Texture&& other) noexcept;
[[nodiscard]] constexpr bool isValid() const noexcept {
2023-12-19 13:10:25 +01:00
return m_textureId != nullptr;
2021-08-18 22:36:46 +02:00
}
[[nodiscard]] operator ImTextureID() const noexcept {
2023-12-19 13:10:25 +01:00
return m_textureId;
2021-08-18 22:36:46 +02:00
}
[[nodiscard]] operator intptr_t() const noexcept {
2023-12-19 13:10:25 +01:00
return reinterpret_cast<intptr_t>(m_textureId);
}
[[nodiscard]] auto getSize() const noexcept {
2023-12-19 13:10:25 +01:00
return ImVec2(m_width, m_height);
2021-08-18 22:36:46 +02:00
}
[[nodiscard]] constexpr auto getAspectRatio() const noexcept {
2023-12-19 13:10:25 +01:00
if (m_height == 0) return 1.0F;
2023-12-19 13:10:25 +01:00
return float(m_width) / float(m_height);
}
private:
ImTextureID m_textureId = nullptr;
int m_width = 0, m_height = 0;
2021-08-18 22:36:46 +02:00
};
2021-12-07 22:47:41 +01:00
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data);
bool IconHyperlink(const char *icon, const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool Hyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool BulletHyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool DescriptionButton(const char *label, const char *description, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool DescriptionButtonProgress(const char *label, const char *description, float fraction, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
2021-01-27 12:04:42 +01:00
void HelpHover(const char *text);
void UnderlinedText(const char *label, ImColor color = ImGui::GetStyleColorVec4(ImGuiCol_Text), const ImVec2 &size_arg = ImVec2(0, 0));
void TextSpinner(const char *label);
void Header(const char *label, bool firstEntry = false);
void HeaderColored(const char *label, ImColor color, bool firstEntry);
bool InfoTooltip(const char *text = "",bool = false);
bool TitleBarButton(const char *label, ImVec2 size_arg);
bool ToolBarButton(const char *symbol, ImVec4 color);
bool IconButton(const char *symbol, ImVec4 color, ImVec2 size_arg = ImVec2(0, 0));
2021-08-21 00:51:50 +02:00
bool InputIntegerPrefix(const char* label, const char *prefix, void *value, ImGuiDataType type, const char *format, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputHexadecimal(const char* label, u32 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputHexadecimal(const char* label, u64 *value, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
2022-02-08 21:10:48 +01:00
2021-06-07 18:13:54 +02:00
inline bool HasSecondPassed() {
return static_cast<ImU32>(ImGui::GetTime() * 100) % 100 <= static_cast<ImU32>(ImGui::GetIO().DeltaTime * 100);
}
void OpenPopupInWindow(const char *window_name, const char *popup_name);
struct ImHexCustomData {
ImVec4 Colors[ImGuiCustomCol_COUNT];
struct Styles {
float WindowBlur = 0.0F;
} styles;
};
ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul = 1.0F);
2021-08-21 00:51:50 +02:00
ImVec4 GetCustomColorVec4(ImGuiCustomCol idx, float alpha_mul = 1.0F);
inline ImHexCustomData::Styles& GetCustomStyle() {
2023-11-30 14:40:07 +01:00
auto &customData = *static_cast<ImHexCustomData *>(ImGui::GetIO().UserData);
return customData.styles;
}
float GetCustomStyleFloat(ImGuiCustomStyle idx);
ImVec2 GetCustomStyleVec2(ImGuiCustomStyle idx);
void StyleCustomColorsDark();
void StyleCustomColorsLight();
void StyleCustomColorsClassic();
void SmallProgressBar(float fraction, float yOffset = 0.0F);
inline void TextFormatted(const std::string &fmt, auto &&...args) {
ImGui::TextUnformatted(hex::format(fmt, std::forward<decltype(args)>(args)...).c_str());
}
inline void TextFormattedSelectable(const std::string &fmt, auto &&...args) {
auto text = hex::format(fmt, std::forward<decltype(args)>(args)...);
ImGui::PushID(text.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
ImGui::PushItemWidth(-FLT_MIN);
ImGui::InputText("##", const_cast<char *>(text.c_str()), text.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::PopItemWidth();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopID();
}
inline void TextFormattedColored(ImColor color, const std::string &fmt, auto &&...args) {
ImGui::TextColored(color, "%s", hex::format(fmt, std::forward<decltype(args)>(args)...).c_str());
}
2022-01-15 14:14:53 +01:00
inline void TextFormattedDisabled(const std::string &fmt, auto &&...args) {
2022-01-15 14:14:53 +01:00
ImGui::TextDisabled("%s", hex::format(fmt, std::forward<decltype(args)>(args)...).c_str());
}
inline void TextFormattedWrapped(const std::string &fmt, auto &&...args) {
2022-01-15 14:14:53 +01:00
ImGui::TextWrapped("%s", hex::format(fmt, std::forward<decltype(args)>(args)...).c_str());
}
inline void TextFormattedWrappedSelectable(const std::string &fmt, auto &&...args) {
// Manually wrap text, using the letter M (generally the widest character in non-monospaced fonts) to calculate the character width to use.
auto text = wolv::util::wrapMonospacedString(
hex::format(fmt, std::forward<decltype(args)>(args)...),
ImGui::CalcTextSize("M").x,
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ScrollbarSize - ImGui::GetStyle().FrameBorderSize
);
ImGui::PushID(text.c_str());
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4());
ImGui::PushItemWidth(-FLT_MIN);
ImGui::InputTextMultiline(
"##",
const_cast<char *>(text.c_str()),
text.size(),
ImVec2(0, -FLT_MIN),
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoHorizontalScroll
);
ImGui::PopItemWidth();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopID();
}
2023-12-02 23:46:20 +01:00
void TextUnformattedCentered(const char *text);
inline void TextFormattedCentered(const std::string &fmt, auto &&...args) {
auto text = hex::format(fmt, std::forward<decltype(args)>(args)...);
2023-12-02 23:46:20 +01:00
TextUnformattedCentered(text.c_str());
}
2023-12-02 23:46:20 +01:00
inline void TextFormattedCenteredHorizontal(const std::string &fmt, auto &&...args) {
auto text = hex::format(fmt, std::forward<decltype(args)>(args)...);
auto availableSpace = ImGui::GetContentRegionAvail();
auto textSize = ImGui::CalcTextSize(text.c_str(), nullptr, false, availableSpace.x * 0.75F);
ImGui::SetCursorPosX(((availableSpace - textSize) / 2.0F).x);
ImGui::PushTextWrapPos(availableSpace.x * 0.75F);
ImGuiExt::TextFormattedWrapped("{}", text);
ImGui::PopTextWrapPos();
}
bool InputTextIcon(const char* label, const char *icon, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
ui/ux: Rewrite of the entire hex editor view to make it more flexible (#512) * ui/ux: Initial recreation of the hex editor view * ui/ux: Added back support for editing cells * ux: Make scrolling and selecting bytes feel nice again * ui/ux: Improved byte selecting, added footer * sys: Make math evaluator more generic to support integer only calculations * patterns: Moved value formatting into pattern language * ui/ux: Added Goto and Search popups, improved selection * ui: Added better tooltips for bookmarks and patterns * sys: Use worse hex search algorithm on macOS Sadly it still doesn't support `std::boyer_moore_horsepool_searcher` * ui: Added back missing events, menu items and shortcuts * fix: Bookmark highlighting being rendered off by one * fix: Various macOS build errors * fix: size_t is not u64 on macos * fix: std::fmod and std::pow not working with integer types on macos * fix: Missing semicolons * sys: Added proper integer pow function * ui: Added back support for custom encodings * fix: Editor not jumping to selection when selection gets changed * ui: Turn Hexii setting into a data visualizer * sys: Added back remaining shortcuts * sys: Remove old hex editor files * sys: Moved more legacy things away from the hex editor view, updated localization * fix: Hex editor scrolling behaving weirdly and inconsistently * sys: Cleaned up Hex editor code * sys: Added selection color setting, localized all new settings * fix: Search feature not working correctly * ui: Replace custom ImGui::Disabled function with native ImGui ones * ui: Fix bookmark tooltip rendering issues * fix: Another size_t not being 64 bit issue on MacOS
2022-05-27 20:42:07 +02:00
bool InputScalarCallback(const char* label, ImGuiDataType data_type, void* p_data, const char* format, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
void HideTooltip();
bool BitCheckbox(const char* label, bool* v);
2023-11-18 17:23:15 +01:00
bool DimmedButton(const char* label, ImVec2 size = ImVec2(0, 0));
bool DimmedIconButton(const char *symbol, ImVec4 color, ImVec2 size = ImVec2(0, 0));
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size);
2023-07-23 09:14:00 +02:00
bool DimmedIconToggle(const char *icon, bool *v);
bool DimmedIconToggle(const char *iconOn, const char *iconOff, bool *v);
void TextOverlay(const char *text, ImVec2 pos);
bool BeginBox();
void EndBox();
2023-11-16 09:32:24 +01:00
void BeginSubWindow(const char *label, ImVec2 size = ImVec2(0, 0), ImGuiChildFlags flags = ImGuiChildFlags_None);
2023-11-15 22:22:57 +01:00
void EndSubWindow();
2023-11-30 14:40:07 +01:00
void ConfirmButtons(const char *textLeft, const char *textRight, const auto &leftButtonCallback, const auto &rightButtonCallback) {
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button(textLeft, ImVec2(width / 3, 0)))
leftButtonCallback();
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button(textRight, ImVec2(width / 3, 0)))
rightButtonCallback();
}
bool VSliderAngle(const char* label, ImVec2& size, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags);
bool InputFilePicker(const char *label, std::fs::path &path, const std::vector<hex::fs::ItemFilter> &validExtensions);
2023-12-07 11:18:49 +01:00
bool ToggleSwitch(const char *label, bool *v);
bool ToggleSwitch(const char *label, bool v);
template<typename T>
constexpr ImGuiDataType getImGuiDataType() {
if constexpr (std::same_as<T, u8>) return ImGuiDataType_U8;
else if constexpr (std::same_as<T, u16>) return ImGuiDataType_U16;
else if constexpr (std::same_as<T, u32>) return ImGuiDataType_U32;
else if constexpr (std::same_as<T, u64>) return ImGuiDataType_U64;
else if constexpr (std::same_as<T, i8>) return ImGuiDataType_S8;
else if constexpr (std::same_as<T, i16>) return ImGuiDataType_S16;
else if constexpr (std::same_as<T, i32>) return ImGuiDataType_S32;
else if constexpr (std::same_as<T, i64>) return ImGuiDataType_S64;
else if constexpr (std::same_as<T, float>) return ImGuiDataType_Float;
else if constexpr (std::same_as<T, double>) return ImGuiDataType_Double;
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
template<typename T>
constexpr const char *getFormatLengthSpecifier() {
if constexpr (std::same_as<T, u8>) return "hh";
else if constexpr (std::same_as<T, u16>) return "h";
else if constexpr (std::same_as<T, u32>) return "l";
else if constexpr (std::same_as<T, u64>) return "ll";
else if constexpr (std::same_as<T, i8>) return "hh";
else if constexpr (std::same_as<T, i16>) return "h";
else if constexpr (std::same_as<T, i32>) return "l";
else if constexpr (std::same_as<T, i64>) return "ll";
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
}
// these functions are exception because they just allow conversion from string to char*, they do not really add anything
namespace ImGui {
bool InputText(const char* label, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputText(const char *label, std::u8string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputTextMultiline(const char* label, std::string &buffer, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
bool InputTextWithHint(const char *label, const char *hint, std::string &buffer, ImGuiInputTextFlags flags = ImGuiInputTextFlags_None);
}