hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ui/icons.h75
-rw-r--r--src/ui/widgets.cpp171
-rw-r--r--src/ui/widgets.h18
3 files changed, 199 insertions, 65 deletions
diff --git a/src/ui/icons.h b/src/ui/icons.h
index 74b0331..22cb04c 100644
--- a/src/ui/icons.h
+++ b/src/ui/icons.h
@@ -6,31 +6,50 @@ namespace Hsdbg
inline constexpr unsigned int ICON_MAX_PH = 0xEE00;
}
-#define ICON_PH_PLAY "\xEE\x8F\x90"
-#define ICON_PH_PAUSE "\xEE\x8E\x9E"
-#define ICON_PH_STOP "\xEE\x91\xAC"
-#define ICON_PH_STEP_OVER "\xEE\x80\x96"
-#define ICON_PH_STEP_INTO "\xEE\x81\x9C"
-#define ICON_PH_STEP_OUT "\xEE\x81\xA6"
-#define ICON_PH_FOLDER "\xEE\x89\x8A"
-#define ICON_PH_FOLDER_OPEN "\xEE\x89\x96"
-#define ICON_PH_FILE "\xEE\x88\xB0"
-#define ICON_PH_FILE_CODE "\xEE\xA4\x94"
-#define ICON_PH_CARET_RIGHT "\xEE\x84\xBA"
-#define ICON_PH_CARET_DOWN "\xEE\x84\xB6"
-#define ICON_PH_STACK "\xEE\x91\xA6"
-#define ICON_PH_BUG "\xEE\x97\xB4"
-#define ICON_PH_SEARCH "\xEE\x8C\x8C"
-#define ICON_PH_GEAR "\xEE\x89\xB2"
-#define ICON_PH_CPU "\xEE\x98\x90"
-#define ICON_PH_LIST "\xEE\x8B\xB0"
-#define ICON_PH_FUNCTION "\xEE\xAF\xA4"
-#define ICON_PH_SLIDERS "\xEE\x90\xB4"
-#define ICON_PH_TERMINAL "\xEE\xAB\xA8"
-#define ICON_PH_DOT "\xEE\xB3\x9E"
-#define ICON_PH_CIRCLE "\xEE\x86\x8A"
-#define ICON_PH_EYE "\xEE\x88\xA0"
-#define ICON_PH_CUBE "\xEE\x87\x9A"
-#define ICON_PH_GAUGE "\xEE\x98\xA8"
-#define ICON_PH_BRANCH "\xEE\x89\xB8"
-#define ICON_PH_BRACKETS "\xEE\xA1\xA0"
+#define ICON_PH_PLAY "\xEE\x8F\x90"
+#define ICON_PH_PAUSE "\xEE\x8E\x9E"
+#define ICON_PH_STOP "\xEE\x91\xAC"
+#define ICON_PH_STEP_OVER "\xEE\x80\x96"
+#define ICON_PH_STEP_INTO "\xEE\x81\x9C"
+#define ICON_PH_STEP_OUT "\xEE\x81\xA6"
+#define ICON_PH_FOLDER "\xEE\x89\x8A"
+#define ICON_PH_FOLDER_OPEN "\xEE\x89\x96"
+#define ICON_PH_FILE "\xEE\x88\xB0"
+#define ICON_PH_FILE_CODE "\xEE\xA4\x94"
+#define ICON_PH_CARET_RIGHT "\xEE\x84\xBA"
+#define ICON_PH_CARET_DOWN "\xEE\x84\xB6"
+#define ICON_PH_STACK "\xEE\x91\xA6"
+#define ICON_PH_BUG "\xEE\x97\xB4"
+#define ICON_PH_SEARCH "\xEE\x8C\x8C"
+#define ICON_PH_GEAR "\xEE\x89\xB0"
+#define ICON_PH_CPU "\xEE\x98\x90"
+#define ICON_PH_LIST "\xEE\x8B\xB0"
+#define ICON_PH_FUNCTION "\xEE\xAF\xA4"
+#define ICON_PH_SLIDERS "\xEE\x90\xB4"
+#define ICON_PH_TERMINAL "\xEE\xAB\xA8"
+#define ICON_PH_DOT "\xEE\xB3\x9E"
+#define ICON_PH_CIRCLE "\xEE\x86\x8A"
+#define ICON_PH_EYE "\xEE\x88\xA0"
+#define ICON_PH_CUBE "\xEE\x87\x9A"
+#define ICON_PH_GAUGE "\xEE\x98\xA8"
+#define ICON_PH_BRANCH "\xEE\x89\xB8"
+#define ICON_PH_BRACKETS "\xEE\xA1\xA0"
+#define ICON_PH_TARGET "\xEE\x91\xBC"
+#define ICON_PH_MAP_PIN "\xEE\x8C\x96"
+#define ICON_PH_HASH "\xEE\x8A\xA2"
+#define ICON_PH_WARNING "\xEE\x93\xA0"
+#define ICON_PH_PLUS "\xEE\x8F\x94"
+#define ICON_PH_PENCIL "\xEE\x8E\xB4"
+#define ICON_PH_CHECK "\xEE\x86\x82"
+#define ICON_PH_X "\xEE\x93\xB6"
+#define ICON_PH_TIMER "\xEE\x92\x92"
+#define ICON_PH_MEMORY "\xEE\xA7\x84"
+#define ICON_PH_PULSE "\xEE\x80\x80"
+#define ICON_PH_FILE_C "\xEE\xAC\xB2"
+#define ICON_PH_FILE_CPP "\xEE\xAC\xAE"
+#define ICON_PH_FILE_RS "\xEE\xAC\xA8"
+#define ICON_PH_CIRCLE_DASHED "\xEE\x98\x82"
+#define ICON_PH_ARROW_RIGHT "\xEE\x81\xAC"
+#define ICON_PH_CLOCK "\xEE\x86\x9A"
+#define ICON_PH_LIGHTNING "\xEE\x8B\x9E"
+#define ICON_PH_INFO "\xEE\x8B\x8E"
diff --git a/src/ui/widgets.cpp b/src/ui/widgets.cpp
index b44a32e..370ea94 100644
--- a/src/ui/widgets.cpp
+++ b/src/ui/widgets.cpp
@@ -1,7 +1,9 @@
#include "ui/widgets.h"
#include <imgui_internal.h>
+#include <misc/cpp/imgui_stdlib.h>
+#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
@@ -15,14 +17,9 @@ namespace Hsdbg::Widgets
ImFont* g_strong = nullptr;
[[maybe_unused]] ImFont* g_mono = nullptr;
- auto accent_color() -> ImVec4
- {
- return ImGui::GetStyle().Colors[ImGuiCol_CheckMark];
- }
-
auto accent_ink() -> ImU32
{
- const ImVec4 a = accent_color();
+ const ImVec4 a = accent();
const float luma = 0.299f * a.x + 0.587f * a.y + 0.114f * a.z;
return luma > 0.6f ? IM_COL32(12, 16, 20, 255) : IM_COL32(245, 247, 250, 255);
}
@@ -32,6 +29,12 @@ namespace Hsdbg::Widgets
colour.w = alpha;
return ImGui::ColorConvertFloat4ToU32(colour);
}
+
+ auto track_fill(ImDrawList* draw, ImVec2 min, ImVec2 max, float rounding) -> void
+ {
+ draw->AddRectFilled(min, max, ImGui::GetColorU32(ImGuiCol_FrameBg), rounding);
+ draw->AddRectFilled(min, max, with_alpha(ImGui::GetStyle().Colors[ImGuiCol_Text], 0.07f), rounding);
+ }
}
auto set_fonts(ImFont* ui, ImFont* strong, ImFont* mono) -> void
@@ -41,7 +44,12 @@ namespace Hsdbg::Widgets
g_mono = mono;
}
- auto section_header(const char* label) -> void
+ auto accent() -> ImVec4
+ {
+ return ImGui::GetStyle().Colors[ImGuiCol_CheckMark];
+ }
+
+ auto section_header(const char* label, bool rule) -> void
{
std::string caps;
caps.reserve(24);
@@ -61,7 +69,7 @@ namespace Hsdbg::Widgets
const ImVec2 hi = ImGui::GetItemRectMax();
const float cy = (lo.y + hi.y) * 0.5f;
const float right = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x;
- if (right > hi.x + 10.0f)
+ if (rule && right > hi.x + 10.0f)
ImGui::GetWindowDrawList()->AddLine(ImVec2(hi.x + 8.0f, cy), ImVec2(right, cy),
ImGui::GetColorU32(ImGuiCol_Border), 1.0f);
}
@@ -70,7 +78,13 @@ namespace Hsdbg::Widgets
{
ImGui::PushID(label);
- const float width = ImGui::CalcItemWidth();
+ char lo[64];
+ char hi[64];
+ std::snprintf(lo, sizeof(lo), fmt, static_cast<double>(min));
+ std::snprintf(hi, sizeof(hi), fmt, static_cast<double>(max));
+ const float value_w = std::max(ImGui::CalcTextSize(lo).x, ImGui::CalcTextSize(hi).x);
+ const float gap = 10.0f;
+ const float width = std::max(ImGui::CalcItemWidth() - value_w - gap, 40.0f);
const float height = ImGui::GetFrameHeight();
const ImVec2 p = ImGui::GetCursorScreenPos();
@@ -90,33 +104,38 @@ namespace Hsdbg::Widgets
const float ty = p.y + (height - th) * 0.5f;
const float frac = (max > min) ? ImClamp((*value - min) / (max - min), 0.0f, 1.0f) : 0.0f;
const float gx = p.x + frac * width;
- const ImU32 accent = ImGui::ColorConvertFloat4ToU32(accent_color());
+ const ImU32 fill = ImGui::ColorConvertFloat4ToU32(accent());
- draw->AddRectFilled(ImVec2(p.x, ty), ImVec2(p.x + width, ty + th),
- ImGui::GetColorU32(ImGuiCol_FrameBg), th * 0.5f);
- draw->AddRectFilled(ImVec2(p.x, ty), ImVec2(gx, ty + th), accent, th * 0.5f);
+ track_fill(draw, ImVec2(p.x, ty), ImVec2(p.x + width, ty + th), th * 0.5f);
+ draw->AddRectFilled(ImVec2(p.x, ty), ImVec2(gx, ty + th), fill, th * 0.5f);
const float r = (active || hovered) ? height * 0.30f : height * 0.26f;
- draw->AddCircleFilled(ImVec2(gx, p.y + height * 0.5f), r, accent);
+ draw->AddCircleFilled(ImVec2(gx, p.y + height * 0.5f), r, fill);
draw->AddCircleFilled(ImVec2(gx, p.y + height * 0.5f), r * 0.42f, accent_ink());
char buf[64];
std::snprintf(buf, sizeof(buf), fmt, static_cast<double>(*value));
const ImVec2 ts = ImGui::CalcTextSize(buf);
- draw->AddText(ImVec2(p.x + (width - ts.x) * 0.5f, p.y + (height - ts.y) * 0.5f),
+ draw->AddText(ImVec2(p.x + width + gap + value_w - ts.x, p.y + (height - ts.y) * 0.5f),
ImGui::GetColorU32(ImGuiCol_Text), buf);
+ ImGui::SameLine(0.0f, 0.0f);
+ ImGui::Dummy(ImVec2(gap + value_w, height));
+
ImGui::PopID();
- ImGui::SameLine();
- ImGui::AlignTextToFramePadding();
- ImGui::TextUnformatted(label);
+ if (label[0] != '#' || label[1] != '#')
+ {
+ ImGui::SameLine();
+ ImGui::AlignTextToFramePadding();
+ ImGui::TextUnformatted(label);
+ }
return *value != before;
}
auto icon_button(const char* id, const char* icon, bool active, const char* tooltip,
- bool disabled, float size) -> bool
+ bool disabled, float size, ImVec4 glyph) -> bool
{
if (disabled)
ImGui::BeginDisabled();
@@ -125,7 +144,7 @@ namespace Hsdbg::Widgets
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 10.0f);
if (active)
- ImGui::PushStyleColor(ImGuiCol_Button, accent_color());
+ ImGui::PushStyleColor(ImGuiCol_Button, accent());
const ImVec2 origin = ImGui::GetCursorScreenPos();
const bool clicked = ImGui::Button("##btn", ImVec2(size, size));
@@ -134,7 +153,9 @@ namespace Hsdbg::Widgets
ImGui::PopStyleColor();
ImGui::PopStyleVar();
- const ImU32 glyph_col = active ? accent_ink() : ImGui::GetColorU32(ImGuiCol_Text);
+ const bool tinted = glyph.w > 0.0f && !disabled && !active;
+ const ImU32 glyph_col = active ? accent_ink()
+ : ImGui::GetColorU32(tinted ? glyph : ImGui::GetStyleColorVec4(ImGuiCol_Text));
const float cx = origin.x + size * 0.5f;
const float cy = origin.y + size * 0.5f;
@@ -179,12 +200,15 @@ namespace Hsdbg::Widgets
const float radius = height * 0.5f;
const ImVec2 end(pos.x + width, pos.y + height);
- const ImU32 track = *value ? ImGui::ColorConvertFloat4ToU32(accent_color())
- : ImGui::GetColorU32(ImGuiCol_FrameBg);
- draw->AddRectFilled(pos, end, track, radius);
- if (!*value)
- draw->AddRect(pos, end, ImGui::GetColorU32(hovered ? ImGuiCol_Border : ImGuiCol_FrameBg),
- radius);
+ if (*value)
+ {
+ draw->AddRectFilled(pos, end, ImGui::ColorConvertFloat4ToU32(accent()), radius);
+ }
+ else
+ {
+ track_fill(draw, pos, end, radius);
+ draw->AddRect(pos, end, ImGui::GetColorU32(hovered ? ImGuiCol_TextDisabled : ImGuiCol_Border), radius);
+ }
const float knob = radius - 2.5f;
const float knob_x = *value ? (end.x - radius) : (pos.x + radius);
@@ -194,6 +218,14 @@ namespace Hsdbg::Widgets
return clicked;
}
+ auto segmented_width(const char* const* labels, int count) -> float
+ {
+ float total = 4.0f;
+ for (int i = 0; i < count; ++i)
+ total += ImGui::CalcTextSize(labels[i]).x + 8.0f * 2.0f + 2.0f;
+ return total;
+ }
+
auto segmented(const char* id, const char* const* labels, int count, int current) -> int
{
const ImGuiStyle& style = ImGui::GetStyle();
@@ -202,13 +234,9 @@ namespace Hsdbg::Widgets
const float height = ImGui::GetFrameHeight();
const float pad = 8.0f;
const ImVec2 origin = ImGui::GetCursorScreenPos();
+ const float total = segmented_width(labels, count);
- float total = 4.0f;
- for (int i = 0; i < count; ++i)
- total += ImGui::CalcTextSize(labels[i]).x + pad * 2.0f + 2.0f;
-
- const ImU32 track = ImGui::GetColorU32(ImGuiCol_FrameBg);
- draw->AddRectFilled(origin, ImVec2(origin.x + total, origin.y + height), track, height * 0.5f);
+ track_fill(draw, origin, ImVec2(origin.x + total, origin.y + height), height * 0.5f);
int result = current;
ImGui::PushID(id);
@@ -266,12 +294,12 @@ namespace Hsdbg::Widgets
ImVec2 max = ImGui::GetItemRectMax();
min.x += 2.0f;
max.x -= 2.0f;
- const ImU32 fill = selected ? with_alpha(accent_color(), 0.18f)
+ const ImU32 fill = selected ? with_alpha(accent(), 0.18f)
: with_alpha(ImGui::GetStyle().Colors[ImGuiCol_Text], 0.055f);
split.SetCurrentChannel(draw, 0);
draw->AddRectFilled(min, max, fill, 7.0f);
if (selected)
- draw->AddRect(min, max, with_alpha(accent_color(), 0.40f), 7.0f);
+ draw->AddRect(min, max, with_alpha(accent(), 0.40f), 7.0f);
}
split.Merge(draw);
@@ -348,4 +376,77 @@ namespace Hsdbg::Widgets
return clicked;
}
+
+ auto input_with_icon(const char* id, const char* icon, const char* hint, std::string* text,
+ ImGuiInputTextFlags flags) -> bool
+ {
+ const ImGuiStyle& style = ImGui::GetStyle();
+ const ImVec2 pos = ImGui::GetCursorScreenPos();
+ const float pad_x = style.FramePadding.x;
+ const float pad_y = style.FramePadding.y;
+
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
+ ImVec2(pad_x * 2.0f + ImGui::CalcTextSize(icon).x, pad_y));
+ const bool changed = ImGui::InputTextWithHint(id, hint, text, flags);
+ ImGui::PopStyleVar();
+
+ ImGui::GetWindowDrawList()->AddText(ImVec2(pos.x + pad_x, pos.y + pad_y),
+ ImGui::GetColorU32(ImGuiCol_TextDisabled), icon);
+ return changed;
+ }
+
+ auto dot_toggle(const char* id, bool* value, ImU32 on, ImU32 off, bool pending) -> bool
+ {
+ const float s = ImGui::GetFrameHeight();
+ const ImVec2 p = ImGui::GetCursorScreenPos();
+
+ ImGui::InvisibleButton(id, ImVec2(s, s));
+ const bool clicked = ImGui::IsItemClicked();
+ if (clicked)
+ *value = !*value;
+
+ const ImVec2 centre(p.x + s * 0.5f, p.y + s * 0.5f);
+ const ImU32 colour = *value ? on : off;
+ ImDrawList* draw = ImGui::GetWindowDrawList();
+ if (pending)
+ draw->AddCircle(centre, 5.0f, colour, 0, 1.5f);
+ else
+ draw->AddCircleFilled(centre, 5.0f, colour);
+
+ if (ImGui::IsItemHovered())
+ ImGui::SetTooltip("%s", *value ? "Disable" : "Enable");
+
+ return clicked;
+ }
+
+ auto hex_value(unsigned long long value, int digits) -> void
+ {
+ char buf[32];
+ std::snprintf(buf, sizeof(buf), "%0*llx", digits, value);
+
+ int zeros = 0;
+ while (zeros < digits - 1 && buf[zeros] == '0')
+ ++zeros;
+
+ ImGui::TextDisabled("0x%.*s", zeros, buf);
+ ImGui::SameLine(0.0f, 0.0f);
+ ImGui::TextUnformatted(buf + zeros);
+ }
+
+ auto link_text(const char* text) -> bool
+ {
+ ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextLink));
+ ImGui::TextUnformatted(text);
+ ImGui::PopStyleColor();
+
+ if (!ImGui::IsItemHovered())
+ return false;
+
+ ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+ const ImVec2 lo = ImGui::GetItemRectMin();
+ const ImVec2 hi = ImGui::GetItemRectMax();
+ ImGui::GetWindowDrawList()->AddLine(ImVec2(lo.x, hi.y - 1.0f), ImVec2(hi.x, hi.y - 1.0f),
+ ImGui::GetColorU32(ImGuiCol_TextLink));
+ return ImGui::IsMouseClicked(ImGuiMouseButton_Left);
+ }
}
diff --git a/src/ui/widgets.h b/src/ui/widgets.h
index dac58e3..366e69a 100644
--- a/src/ui/widgets.h
+++ b/src/ui/widgets.h
@@ -2,22 +2,27 @@
#include <imgui.h>
+#include <string>
+
namespace Hsdbg::Widgets
{
auto set_fonts(ImFont* ui, ImFont* strong, ImFont* mono) -> void;
- auto section_header(const char* label) -> void;
+ auto accent() -> ImVec4;
+
+ auto section_header(const char* label, bool rule = true) -> void;
auto slider_float(const char* label, float* value, float min, float max,
const char* fmt) -> bool;
auto icon_button(const char* id, const char* icon, bool active = false,
const char* tooltip = nullptr, bool disabled = false,
- float size = 34.0f) -> bool;
+ float size = 34.0f, ImVec4 glyph = ImVec4(0.0f, 0.0f, 0.0f, 0.0f)) -> bool;
auto toggle(const char* id, bool* value) -> bool;
auto segmented(const char* id, const char* const* labels, int count, int current) -> int;
+ auto segmented_width(const char* const* labels, int count) -> float;
auto selectable_row(const char* label, bool selected,
ImGuiSelectableFlags flags = 0) -> bool;
@@ -27,4 +32,13 @@ namespace Hsdbg::Widgets
auto empty_state(const char* icon, const char* text) -> void;
auto remove_button(const char* id) -> bool;
+
+ auto input_with_icon(const char* id, const char* icon, const char* hint, std::string* text,
+ ImGuiInputTextFlags flags = 0) -> bool;
+
+ auto dot_toggle(const char* id, bool* value, ImU32 on, ImU32 off, bool pending = false) -> bool;
+
+ auto hex_value(unsigned long long value, int digits) -> void;
+
+ auto link_text(const char* text) -> bool;
}