Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/external/libwolv
2 changes: 1 addition & 1 deletion lib/external/pattern_language
55 changes: 48 additions & 7 deletions lib/libimhex/include/hex/ui/imgui_imhex_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstddef>
#include <string>
#include <span>
#include <variant>

#include <imgui.h>

Expand Down Expand Up @@ -63,6 +64,7 @@ enum ImGuiCustomCol : int {

enum ImGuiCustomStyle {
ImGuiCustomStyle_WindowBlur,
ImGuiCustomStyle_PopupWindowAlpha,

ImGuiCustomStyle_COUNT
};
Expand Down Expand Up @@ -172,21 +174,60 @@ namespace ImGuiExt {
struct ImHexCustomData {
ImVec4 Colors[ImGuiCustomCol_COUNT];

struct Styles {
struct StyleData {
float WindowBlur = 0.0F;
float PopupWindowAlpha = 0.0F; // Alpha used by Popup tool windows when the user is not hovering over them
} styles;
} Styles;
};

ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul = 1.0F);
ImVec4 GetCustomColorVec4(ImGuiCustomCol idx, float alpha_mul = 1.0F);
using StyleVariantType = std::variant<float, ImVec2>;

struct StyleTypeRef {
size_t VariantIndex;
size_t Offset;
};

struct ImGuiExStyleMod {
StyleTypeRef Ref;
StyleVariantType BackupValue;
};

struct ImGuiExColorMod {
ImGuiCol Col;
ImVec4 BackupValue;
};

inline ImHexCustomData::Styles& GetCustomStyle() {
auto &customData = *static_cast<ImHexCustomData *>(ImGui::GetIO().UserData);
struct ImGuiExtContext {
ImHexCustomData Data;

// Stacks
ImVector<ImGuiExColorMod> ColorStack;
ImVector<ImGuiExStyleMod> StyleStack;
};

return customData.styles;
inline ImGuiExtContext& GetContext() {
return *static_cast<ImGuiExtContext *>(ImGui::GetIO().UserData);
}

inline ImHexCustomData& GetCustomData() {
return GetContext().Data;
}

inline ImHexCustomData::StyleData& GetCustomStyle() {
return GetCustomData().Styles;
}

void PushCustomColor(ImGuiCustomCol idx, ImU32 col);
void PushCustomColor(ImGuiCustomCol idx, const ImVec4& col);
void PopCustomColor(int count = 1);

void PushStyle(ImGuiCustomStyle idx, float val);
void PushStyle(ImGuiCustomStyle idx, const ImVec2 &val);
void PopStyle(int count = 1);

ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul = 1.0F);
ImVec4 GetCustomColorVec4(ImGuiCustomCol idx, float alpha_mul = 1.0F);

float GetCustomStyleFloat(ImGuiCustomStyle idx);
ImVec2 GetCustomStyleVec2(ImGuiCustomStyle idx);

Expand Down
128 changes: 113 additions & 15 deletions lib/libimhex/source/ui/imgui_imhex_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,45 @@
#include <string>
#include <algorithm>
#include <numbers>
#include <type_traits>

#include <hex/api/imhex_api/system.hpp>

#include <hex/api/task_manager.hpp>
#include <hex/api/theme_manager.hpp>
#include <hex/helpers/logger.hpp>
#include <wolv/utils/variant_type_index.hpp>

namespace ImGuiExt {

using namespace ImGui;

namespace {

template <typename Class, typename Member>
constexpr StyleTypeRef toStyleRef(Member Class::*member)
{
const size_t off = reinterpret_cast<size_t>(&(reinterpret_cast<Class const volatile*>(0)->*member));
return {wolv::util::VariantTypeIndex<Member, StyleVariantType>, off};
};

const StyleTypeRef s_StyleReferences[] = {
toStyleRef(&ImHexCustomData::StyleData::WindowBlur),
toStyleRef(&ImHexCustomData::StyleData::PopupWindowAlpha)
};

template <typename V>
inline V& getStyleValue(ImGuiExtContext &g, const StyleTypeRef &ref) {
V &value = *reinterpret_cast<V*>(reinterpret_cast<char*>(&g.Data.Styles)+ref.Offset);
return value;
}

template <typename V>
inline void writeStyleValue(ImGuiExtContext &g, const StyleTypeRef &ref, const V &val) {
V &value = getStyleValue<V>(g, ref);
value = val;
}

bool isOpenGLExtensionSupported(const char *name) {
static std::set<std::string> extensions;

Expand Down Expand Up @@ -684,38 +710,110 @@ namespace ImGuiExt {
return result;
}

void PushCustomColor(ImGuiCustomCol idx, ImU32 col) {
ImGuiExtContext &g = GetContext();
ImGuiExColorMod backup;
backup.Col = idx;
backup.BackupValue = g.Data.Colors[idx];
g.ColorStack.push_back(backup);
g.Data.Colors[idx] = ColorConvertU32ToFloat4(col);
}

void PushCustomColor(ImGuiCustomCol idx, const ImVec4& col) {
ImGuiExtContext &g = GetContext();
ImGuiExColorMod backup;
backup.Col = idx;
backup.BackupValue = g.Data.Colors[idx];
g.ColorStack.push_back(backup);
g.Data.Colors[idx] = col;
}

void PopCustomColor(int count) {
ImGuiExtContext &g = GetContext();
if (g.ColorStack.Size < count)
{
IM_ASSERT_USER_ERROR(0, "Calling ImGUiExt::PopCustomColor() too many times!");
count = g.ColorStack.Size;
}
while (count > 0)
{
ImGuiExColorMod &backup = g.ColorStack.back();
g.Data.Colors[backup.Col] = backup.BackupValue;
g.ColorStack.pop_back();
count--;
}
}

void PushStyle(ImGuiCustomStyle idx, float val) {
ImGuiExtContext &g = GetContext();
ImGuiExStyleMod backup;
backup.Ref = s_StyleReferences[idx];
if (backup.Ref.VariantIndex != wolv::util::VariantTypeIndex<float, StyleVariantType>) {
assert(!"ImGuiExt::PushStyle: idx is not a float style");
return;
}
backup.BackupValue = getStyleValue<float>(g, backup.Ref);
g.StyleStack.push_back(backup);
writeStyleValue(g, backup.Ref, val);
}

void PushStyle(ImGuiCustomStyle idx, const ImVec2 &val) {
ImGuiExtContext &g = GetContext();
ImGuiExStyleMod backup;
backup.Ref = s_StyleReferences[idx];
if (backup.Ref.VariantIndex != wolv::util::VariantTypeIndex<ImVec2, StyleVariantType>) {
assert(!"ImGuiExt::PushStyle: idx is not an ImVec2 style");
return;
}
backup.BackupValue = getStyleValue<ImVec2>(g, backup.Ref);
g.StyleStack.push_back(backup);
writeStyleValue(g, backup.Ref, val);
}

void PopStyle(int count) {
ImGuiExtContext &g = GetContext();
if (g.StyleStack.Size < count)
{
IM_ASSERT_USER_ERROR(0, "Calling ImGUiExt::PopStyle() too many times!");
count = g.StyleStack.Size;
}
while (count > 0)
{
ImGuiExStyleMod &backup = g.StyleStack.back();
writeStyleValue(g, backup.Ref, std::get<float>(backup.BackupValue));
g.StyleStack.pop_back();
count--;
}
}

ImU32 GetCustomColorU32(ImGuiCustomCol idx, float alpha_mul) {
auto &customData = *static_cast<ImHexCustomData *>(GImGui->IO.UserData);
auto &customData = GetCustomData();
ImVec4 c = customData.Colors[idx];
c.w *= GImGui->Style.Alpha * alpha_mul;
return ColorConvertFloat4ToU32(c);
}

ImVec4 GetCustomColorVec4(ImGuiCustomCol idx, float alpha_mul) {
auto &customData = *static_cast<ImHexCustomData *>(GImGui->IO.UserData);
auto &customData = GetCustomData();
ImVec4 c = customData.Colors[idx];
c.w *= GImGui->Style.Alpha * alpha_mul;
return c;
}

float GetCustomStyleFloat(ImGuiCustomStyle idx) {
auto &customData = *static_cast<ImHexCustomData *>(GImGui->IO.UserData);

switch (idx) {
case ImGuiCustomStyle_WindowBlur:
return customData.styles.WindowBlur;
default:
return 0.0F;
}
assert((s_StyleReferences[idx].VariantIndex == wolv::util::VariantTypeIndex<float, StyleVariantType>));
ImGuiExtContext &g = GetContext();
return getStyleValue<float>(g, s_StyleReferences[idx]);
}

ImVec2 GetCustomStyleVec2(ImGuiCustomStyle idx) {
std::ignore = idx;
return {};
assert((s_StyleReferences[idx].VariantIndex == wolv::util::VariantTypeIndex<float, StyleVariantType>));
ImGuiExtContext &g = GetContext();
return getStyleValue<ImVec2>(g, s_StyleReferences[idx]);
}

void StyleCustomColorsDark() {
auto &colors = static_cast<ImHexCustomData *>(GImGui->IO.UserData)->Colors;
auto &colors = GetCustomData().Colors;

colors[ImGuiCustomCol_DescButton] = ImColor(20, 20, 20);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(40, 40, 40);
Expand All @@ -737,7 +835,7 @@ namespace ImGuiExt {
}

void StyleCustomColorsLight() {
auto &colors = static_cast<ImHexCustomData *>(GImGui->IO.UserData)->Colors;
auto &colors = GetCustomData().Colors;

colors[ImGuiCustomCol_DescButton] = ImColor(230, 230, 230);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(210, 210, 210);
Expand All @@ -759,7 +857,7 @@ namespace ImGuiExt {
}

void StyleCustomColorsClassic() {
auto &colors = static_cast<ImHexCustomData *>(GImGui->IO.UserData)->Colors;
auto &colors = GetCustomData().Colors;

colors[ImGuiCustomCol_DescButton] = ImColor(40, 40, 80);
colors[ImGuiCustomCol_DescButtonHovered] = ImColor(60, 60, 100);
Expand Down
2 changes: 1 addition & 1 deletion main/gui/include/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace hex {

std::set<int> m_pressedKeys;

ImGuiExt::ImHexCustomData m_imguiCustomData;
ImGuiExt::ImGuiExtContext m_imguiExtContext;

bool m_emergencyPopupOpen = false;
bool m_shouldUnlockFrameRate = false;
Expand Down
2 changes: 1 addition & 1 deletion main/gui/source/window/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,7 @@ namespace hex {
ImNodes::GetIO().LinkDetachWithModifierClick.Modifier = &always;
}

io.UserData = &m_imguiCustomData;
io.UserData = &m_imguiExtContext;

style.ScaleAllSizes(ImHexApi::System::getGlobalScale());
auto scale = ImHexApi::System::getNativeScale();
Expand Down
9 changes: 4 additions & 5 deletions plugins/builtin/source/content/themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,11 @@ namespace hex::plugin::builtin {

ThemeManager::addThemeHandler("imhex", ImHexColorMap,
[](u32 colorId) -> ImColor {
return static_cast<ImGuiExt::ImHexCustomData *>(ImGui::GetCurrentContext()->IO.UserData)->Colors[colorId];
return ImGuiExt::GetCustomData().Colors[colorId];

},
[](u32 colorId, ImColor color) {
static_cast<ImGuiExt::ImHexCustomData *>(ImGui::GetCurrentContext()->IO.UserData)->Colors[colorId] = color;
ImGuiExt::GetCustomData().Colors[colorId] = color;
}
);
}
Expand Down Expand Up @@ -396,10 +396,9 @@ namespace hex::plugin::builtin {
}

{
auto &style = ImGuiExt::GetCustomStyle();
const static ThemeManager::StyleMap ImHexStyleMap = {
{ "window-blur", { .value=&style.WindowBlur, .min=0.0F, .max=1.0F, .needsScaling=true } },
{ "popup-alpha", { .value=&style.PopupWindowAlpha, .min=0.0F, .max=1.0F, .needsScaling=false } },
{ "window-blur", { .value=&ImGuiExt::GetCustomStyle().WindowBlur, .min=0.0F, .max=1.0F, .needsScaling=true } },
{ "popup-alpha", { .value=&ImGuiExt::GetCustomStyle().PopupWindowAlpha, .min=0.0F, .max=1.0F, .needsScaling=false } },
};

ThemeManager::addStyleHandler("imhex", ImHexStyleMap);
Expand Down