ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.99k stars 10.29k forks source link

Optional highlighting for InputText-based widgets #3411

Open Vennor opened 4 years ago

Vennor commented 4 years ago

Hi! Currently widgets like ComboBox or Checkbox offer highlighting both for hovered and active state. The same is not true for InputText-based widgets.

We already briefly touched the subject on Discord where the reason why there's no highlight was worded like below.

(...) it seemed less distracting, unlike other widgets which are often active for a short amount of time, InputText() tend to stay active longer.

I agree with that but it also heavily depends on the color style. In my case the differences aren't vast enough to call it distracting and I'd like to have coherent widget behavior.

The only difference in code seems to be that InputText doesn't check the state and color its background so it's trivial to change.

To allow toggling between the current behavior and enabled highlighting we could use ImGuiInputTextFlags and only highlight when a proper flag is rised.

I can do it and make a PR. How do you feel about it?

ocornut commented 6 months ago

Sorry for lack of answer, better late than never.. I was under the impression there was a more complete topic about this and the underlying reasoning, but it might have been a RIP-Discord-only chat.

The code in InputTextEx() could be changed from:

    // Render frame
    if (!is_multiline)
    {
        RenderNavHighlight(frame_bb, id);
--      RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
++      RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32((hovered || g.ActiveId == id) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
    }

And for multi-line:

        // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug.
--      PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]);
++      const bool use_hovered_bg = (g.ActiveId == id) || (g.HoveredWindow && g.HoveredWindow->ChildId == id);
++      PushStyleColor(ImGuiCol_ChildBg, style.Colors[use_hovered_bg ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg]);

(1) It looks ok with default dark theme, but IMHO rather unusually noisy with StyleColorsLight(). I am not sure how to tackle that yet.

(2) That's not using FrameBgActive so technically still inconsistent, I feel like adding this would be even more noisy for all themes. Note that other items using FrameBgActive are activated for short amounts of time whereas InputText() fields tends to left activated.

(3) I am also not sure how to tackle that for multi-line fields, which tends to be larger and therefore things are largely noticeable.

ocornut commented 6 months ago

We may be able to tackle this by:

An alternative that a bit less consistent but IMHO easier to apply would be to replace

GetColorU32((hovered || g.ActiveId == id) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg)

with

GetColorU32((hovered && g.ActiveId != id) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg)

Aka only ever using that color on hover prior to activation.