Skip to content

Commit

Permalink
Support saving UI Debugger settings in imgui.ini
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed Jan 15, 2025
1 parent 3e950d2 commit 77ba51a
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 20 deletions.
11 changes: 11 additions & 0 deletions src/xrEngine/editor_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ inline bool InputText(pcstr label, shared_str& texture_name)
return false;
}

inline bool ColorEdit4(pcstr label, u32& clr, ImGuiColorEditFlags flags = 0)
{
Fcolor color = clr;
if (ImGui::ColorEdit4(label, reinterpret_cast<float*>(&color), flags))
{
clr = color.get();
return true;
}
return false;
}

inline ImGuiKey xr_key_to_imgui_key(int key)
{
switch (key)
Expand Down
30 changes: 18 additions & 12 deletions src/xrUICore/Windows/UIWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,36 +532,42 @@ bool CUIWindow::FillDebugTree(const CUIDebugState& debugState)
if (ImGui::IsItemClicked())
debugState.select(this);

const bool hovered = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled);
if (debugState.drawWndRects && (IsShown() || hovered))
const bool examined = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled);
if (debugState.settings.drawWndRects && (IsShown() || examined))
{
const auto& focus = UI().Focus();
auto& colors = debugState.settings.colors;

Frect rect;
GetAbsoluteRect(rect);
UI().ClientToScreenScaled(rect.lt, rect.lt.x, rect.lt.y);
UI().ClientToScreenScaled(rect.rb, rect.rb.x, rect.rb.y);

// XXX: make colours user configurable
const u32 alpha = CursorOverWindow() ? 255 : 200;
Fcolor color = color_rgba(0, 0, 255, alpha);
if (hovered)
color = color_rgba(0, 255, 255, 255);
Fcolor color;
const bool hovered = CursorOverWindow();

if (examined)
color = colors.examined;
else if (focus.GetFocused() == this)
color = color_rgba(255, 215, 0, 255);
else if (debugState.coloredRects)
color = colors.focused;
else if (debugState.settings.coloredRects)
{
const u32 alpha = hovered ? 255 : 200;
// This is pseudo RNG, so when we are seeding it with 'this' pointer
// we can expect predictable and stable values (no *blinking* at all)
CRandom rnd;
rnd.seed((s32)(intptr_t)this);
color = color_rgba(rnd.randI(255), rnd.randI(255), rnd.randI(255), alpha);
}
else if (focus.IsRegistered(this))
color = color_rgba(0, 255, 0, alpha);
else if (focus.IsValuable(this))
color = hovered ? colors.focusableValuableHovered : colors.focusableValuable;
else if (focus.IsNonValuable(this))
color = hovered ? colors.focusableNonValuableHovered : colors.focusableNonValuable;
else
color = hovered ? colors.normalHovered : colors.normal;

const auto mainVP = ImGui::GetMainViewport();
const auto draw_list = hovered ? ImGui::GetForegroundDrawList(mainVP) : ImGui::GetBackgroundDrawList(mainVP);
const auto draw_list = examined ? ImGui::GetForegroundDrawList(mainVP) : ImGui::GetBackgroundDrawList(mainVP);
draw_list->AddRect((const ImVec2&)rect.lt, (const ImVec2&)rect.rb, color.get_windows());
}

Expand Down
147 changes: 142 additions & 5 deletions src/xrUICore/ui_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "ui_debug.h"
#include "ui_base.h"
#include "xrEngine/editor_helper.h"

CUIDebuggable::~CUIDebuggable()
{
Expand Down Expand Up @@ -57,6 +58,7 @@ CUIDebugger::CUIDebugger()
}
);
ImGui::SetCurrentContext(Device.GetImGuiContext());
reset_settings();
}

void CUIDebugger::on_tool_frame()
Expand All @@ -65,16 +67,45 @@ void CUIDebugger::on_tool_frame()
if (!get_open_state())
return;

using namespace xray;

if (ImGui::Begin(tool_name(), &get_open_state(), get_default_window_flags()))
{
if (ImGui::BeginMenuBar())
{
ImGui::Checkbox("Draw rects", &m_state.drawWndRects);

ImGui::BeginDisabled(!m_state.drawWndRects);
ImGui::Checkbox("Coloured rects", &m_state.coloredRects);
ImGui::EndDisabled();
ImGui::Checkbox("Draw rects", &m_state.settings.drawWndRects);

if (ImGui::BeginMenu("Options"))
{
ImGui::Checkbox("Randomly coloured rects", &m_state.settings.coloredRects);

ImGui::Text("");
ImGui::Text("Rect colouring:");

auto& colors = m_state.settings.colors;

imgui::ColorEdit4("Normal", colors.normal);
imgui::ItemHelp("Just a normal window");
imgui::ColorEdit4("Normal hovered", colors.normalHovered);
imgui::ItemHelp("Just a normal window hovered by in-game cursor");
imgui::ColorEdit4("Examined", colors.examined);
imgui::ItemHelp("A window that is hovered here, in the tree of the UI Debugger");
imgui::ColorEdit4("Focused", colors.focused);
imgui::ItemHelp("Window currectly selected in the focus system");

ImGui::BeginDisabled(m_state.settings.coloredRects);
imgui::ColorEdit4("Valuable focusable", colors.focusableValuable);
imgui::ItemHelp("Window that is currently valuable in the focus system");
imgui::ColorEdit4("Valuable focusable hovered", colors.focusableValuableHovered);
imgui::ItemHelp("Valuable window hovered by in-game cursor");
imgui::ColorEdit4("Non valuable focusable", colors.focusableNonValuable);
imgui::ItemHelp("Window that is currently non-valuable in the focus system");
imgui::ColorEdit4("Non valuable focusable hovered", colors.focusableNonValuableHovered);
imgui::ItemHelp("Non-valuable window hovered by in-game cursor");
ImGui::EndDisabled();

ImGui::EndMenu();
}
ImGui::EndMenuBar();
}

Expand Down Expand Up @@ -105,3 +136,109 @@ void CUIDebugger::on_tool_frame()
ImGui::End();
#endif
}

void CUIDebugger::reset_settings()
{
CUIDebuggerSettings settings
{
{
/*.normal =*/ color_rgba(0, 0, 255, 200),
/*.normalHovered =*/ color_rgba(0, 0, 255, 255),
/*.examined =*/ color_rgba(0, 255, 255, 255),
/*.focused =*/ color_rgba(255, 215, 0, 255),
/*.focusableValuable =*/ color_rgba(0, 255, 0, 200),
/*.focusableValuableHovered =*/ color_rgba(0, 255, 0, 255),
/*.focusableNonValuable =*/ color_rgba(255, 0, 0, 200),
/*.focusableNonValuableHovered =*/ color_rgba(255, 0, 0, 255),
},
/*.drawWndRects =*/ true,
/*.coloredRects =*/ false,
};
m_state.settings = settings;
}

void CUIDebugger::apply_setting(pcstr line)
{
auto& settings = m_state.settings;

int i{};
u32 color{};

if (sscanf(line, "ColoredRects=%d", &i) == 1)
settings.coloredRects = i != 0;
else if (sscanf(line, "NormalColor=0x%X", &color) == 1)
settings.colors.normal = color;
else if (sscanf(line, "NormalHoveredColor=0x%X", &color) == 1)
settings.colors.normalHovered = color;
else if (sscanf(line, "ExaminedColor=0x%X", &color) == 1)
settings.colors.examined = color;
else if (sscanf(line, "FocusedColor=0x%X", &color) == 1)
settings.colors.focused = color;
else if (sscanf(line, "FocusableValuableColor=0x%X", &color) == 1)
settings.colors.focusableValuable = color;
else if (sscanf(line, "FocusableValuableHoveredColor=0x%X", &color) == 1)
settings.colors.focusableValuableHovered = color;
else if (sscanf(line, "FocusableNonValuableColor=0x%X", &color) == 1)
settings.colors.focusableNonValuable = color;
else if (sscanf(line, "FocusableNonValuableHoveredColor=0x%X", &color) == 1)
settings.colors.focusableNonValuableHovered = color;
}

void CUIDebugger::save_settings(ImGuiTextBuffer* buffer) const
{
R_ASSERT1_CURE(buffer, return);

const auto& settings = m_state.settings;
const auto& colors = settings.colors;

buffer->appendf("ColoredRects=%d\n", settings.coloredRects);
buffer->appendf("NormalColor=0x%X\n", colors.normal);
buffer->appendf("NormalHoveredColor=0x%X\n", colors.normalHovered);
buffer->appendf("ExaminedColor=0x%X\n", colors.examined);
buffer->appendf("FocusedColor=0x%X\n", colors.focused);
buffer->appendf("FocusableValuableColor=0x%X\n", colors.focusableValuable);
buffer->appendf("FocusableValuableHoveredColor=0x%X\n", colors.focusableValuableHovered);
buffer->appendf("FocusableNonValuableColor=0x%X\n", colors.focusableNonValuable);
buffer->appendf("FocusableNonValuableHoveredColor=0x%X\n", colors.focusableNonValuableHovered);
}

size_t CUIDebugger::estimate_settings_size() const
{
// Additional space for '\n' will be also reserved
// because std::size also counts '\0'

constexpr size_t NUMBER_SIZE = 1; // number serving as bool
constexpr size_t HEXNUMBER_SIZE = 8; // 8 for the 32-bit value in hexadecimal format

// Count bytes for each line
size_t size = 0;

// "ColoredRects=%d\n"
size += std::size("ColoredRects=") + NUMBER_SIZE;

// "NormalColor=0x%X\n"
size += std::size("NormalColor=0x") + HEXNUMBER_SIZE;

// "NormalHoveredColor=0x%X\n"
size += std::size("NormalHoveredColor=0x") + HEXNUMBER_SIZE;

// "ExaminedColor=0x%X\n"
size += std::size("ExaminedColor=0x") + HEXNUMBER_SIZE;

// "FocusedColor=0x%X\n"
size += std::size("FocusedColor=0x") + HEXNUMBER_SIZE;

// "FocusableValuableColor=0x%X\n"
size += std::size("FocusableValuableColor=0x") + HEXNUMBER_SIZE;

// "FocusableValuableHoveredColor=0x%X\n"
size += std::size("FocusableValuableHoveredColor=0x") + HEXNUMBER_SIZE;

// "FocusableNonValuableColor=0x%X\n"
size += std::size("FocusableNonValuableColor=0x") + HEXNUMBER_SIZE;

// "FocusableNonValuableHoveredColor=0x%X\n"
size += std::size("FocusableNonValuableHoveredColor=0x") + HEXNUMBER_SIZE;

return size;
}
37 changes: 34 additions & 3 deletions src/xrUICore/ui_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,38 @@ class XR_NOVTABLE XRUICORE_API CUIDebuggable

inline pcstr CUIDebuggable::GetDebugType() { return "CUIDebuggable"; }

struct CUIDebuggerSettings
{
struct
{
// Just a window
u32 normal;
// Just a window hovered by in-game cursor
u32 normalHovered;
// Any window that is hovered in the ImGui UI Debugger window
u32 examined;
// Window selected in the focus system
u32 focused;
// Window that is currently valuable in the focus system
u32 focusableValuable;
// Valuable window hovered by in-game cursor
u32 focusableValuableHovered;
// Window that is currently non-valuable in the focus system
u32 focusableNonValuable;
// Non-valuable window hovered by in-game cursor
u32 focusableNonValuableHovered;
} colors;

bool drawWndRects;
bool coloredRects;
};

struct CUIDebugState
{
CUIDebuggable* selected{};
mutable CUIDebuggable* newSelected{};
bool drawWndRects{ true };
bool coloredRects{ true };

CUIDebuggerSettings settings;

void select(CUIDebuggable* debuggable) const
{
Expand Down Expand Up @@ -52,8 +78,13 @@ class XRUICORE_API CUIDebugger final : public xray::editor::ide_tool
void SetSelected(CUIDebuggable* debuggable);

[[nodiscard]]
bool ShouldDrawRects() const { return m_state.drawWndRects; }
bool ShouldDrawRects() const { return m_state.settings.drawWndRects; }

private:
pcstr tool_name() const override { return "UI Debugger"; }

void reset_settings() override;
void apply_setting(pcstr line) override;
void save_settings(ImGuiTextBuffer* buffer) const override;
size_t estimate_settings_size() const override;
};

0 comments on commit 77ba51a

Please sign in to comment.