imgui
imgui copied to clipboard
Colorize query status results and highlight on change
(Duplicate of #7074, but taken from a different source branch - same code as https://github.com/ocornut/imgui/commit/1e74fb0e6df988689c4f46ebf42f0b8d8d993ffb, but with updated based branch, fix for build check, and minor formatting)
In the demo, when query the item and window statuses, colorize the background to make the boolean values more visible (green/red for true/false, blue for others).
Also, at high FPS, it's very hard to see when the value changes, especially when it's transient, like the return value or clicks. So make the changes more visible by flashing the background.
example:
https://github.com/ocornut/imgui/assets/1198364/4c0a8853-c191-45c8-b45c-a5dce6862d97
...with the mouse hovering the child window, which Windows Snip tool doesn't capture 😞
See #7074 for old discussion
Haven't polished this much but it seems like using this strategy we can roughly divide the number of lines per 3:
struct ItemStateHistory
{
void DisplayList(int dummy, ...)
{
const float curr_time = (float)ImGui::GetTime();
const float circle_radius = ImGui::GetFontSize() * 0.5f;
ImGuiStorage* storage = ImGui::GetStateStorage();
va_list args;
va_start(args, dummy);
while (const char* item_name = va_arg(args, const char*))
{
float* p_storage = storage->GetFloatRef(ImGui::GetID(item_name), 0.0f);
const bool item_value = va_arg(args, bool);
const bool stored_value = (*p_storage >= 0.0f);
const float stored_time = fabsf(*p_storage);
if (stored_value != item_value)
*p_storage = curr_time * (item_value ? +1.0f : -1.0f);
const float FADE_DELAY = 1.0f; // Time in seconds before a values if considered "old"
const float fade = IM_CLAMP((stored_time + FADE_DELAY - curr_time) / FADE_DELAY, 0.0f, 1.0f);
ImVec4 color = item_value ? ImVec4(0.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
color.w *= 0.25f + fade * 0.75f; // Old values use alpha 0.25, new values use alpha 1.0f
ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddCircleFilled(ImVec2(p.x + circle_radius, p.y + circle_radius), circle_radius, ImGui::GetColorU32(color));
ImGui::Dummy(ImVec2(circle_radius * 2.0f, circle_radius * 2.0f));
ImGui::SameLine();
ImGui::Text("%s = %d", item_name, item_value);
}
va_end(args);
}
};
static ItemStateHistory sh;
sh.DisplayList(
0,
"Return value", ret,
"IsItemFocused()", ImGui::IsItemFocused(),
"IsItemHovered()", ImGui::IsItemHovered(),
"IsItemHovered(_AllowWhenBlockedByPopup)", ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
"IsItemHovered(_AllowWhenBlockedByActiveItem)", ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
"IsItemHovered(_AllowWhenOverlappedByItem)", ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByItem),
"IsItemHovered(_AllowWhenOverlappedByWindow)", ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow),
"IsItemHovered(_AllowWhenDisabled)", ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled),
"IsItemHovered(_RectOnly)", ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
"IsItemActive()", ImGui::IsItemActive(),
"IsItemEdited()", ImGui::IsItemEdited(),
"IsItemActivated()", ImGui::IsItemActivated(),
"IsItemDeactivated()", ImGui::IsItemDeactivated(),
"IsItemDeactivatedAfterEdit()", ImGui::IsItemDeactivatedAfterEdit(),
"IsItemVisible()", ImGui::IsItemVisible(),
"IsItemClicked()", ImGui::IsItemClicked(),
"IsItemToggledOpen()", ImGui::IsItemToggledOpen(),
NULL);
It may makes sense to not try to supported Rect/Vec2 too much and display those on separate lines, but maybe there's a path to support it.