imgui icon indicating copy to clipboard operation
imgui copied to clipboard

Colorize query status results and highlight on change

Open Nahor opened this issue 1 year ago • 2 comments

(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

image ...with the mouse hovering the child window, which Windows Snip tool doesn't capture 😞

Nahor avatar Dec 12 '23 21:12 Nahor

See #7074 for old discussion

Nahor avatar Dec 12 '23 21:12 Nahor

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.

ocornut avatar Dec 19 '23 18:12 ocornut