Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there an official way to turn off highlight during hover for Selectable() but keep the other functionalities #8106

Closed
pbakota opened this issue Oct 27, 2024 · 5 comments

Comments

@pbakota
Copy link

pbakota commented Oct 27, 2024

Version/Branch of Dear ImGui:

1.91.3 WIP (19124) docking

Back-ends:

imgui_impl_sdl2.h + imgui_impl_sdlrenderer2.h

Compiler, OS:

gcc version 11.4.0

Full config/build information:

Dear ImGui 1.91.3 WIP (19124)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201103
define: __linux__
define: __GNUC__=11
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_sdlrenderer2
io.ConfigFlags: 0x00000080
 DockingEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00000C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1918.00,1038.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 0.00,0.00
style.WindowBorderSize: 0.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

I am using a table to render some data with full row selection. My table rows are taller than usual (I have a thumbnail image in it), and the highlighting of the tall row during hover with flashing color is very disturbing. So, I'm wondering is there any out-of-the-box solution which I can use to turn off highlighting the table row during hover. I have checked the source code of the Selectable() function and looked at the available flags as well, but I could not find any solution that can cover my use case. After looking at the Selectable() function for me, it seems like this kind of feature is not supported currently. I managed to solve the problem on my own, by adding my own flag "ImGuiSelectableFlags_NoHover" which then I handle in line 6985:

const bool highlighted = (flags & ImGuiSelectableFlags_NoHover ? 0 : hovered) || (flags & ImGuiSelectableFlags_Highlight);

But my solution requires modifying the core code of the ImGui which I rather do not want to do if I have any other official solution. As for a quick solution, I already tried to set the hover color to the background color, but then I had some minor rendering problems with borders.

@ocornut
Copy link
Owner

ocornut commented Oct 27, 2024

My table rows are taller than usual (I have a thumbnail image in it), and the highlighting of the tall row during hover with flashing color is very disturbing.

Could you clarify what this means?

@pbakota
Copy link
Author

pbakota commented Oct 27, 2024

Here is my screenshot. I don't want to highlight the row during hover (hover highlight), but I still want to be able to mark the selected row (selected item)

2024-10-27_23-44

When I'm moving the mouse from one row to another, that row will change the background color from dark to highlight color and that move will create flashing on the screen.

@GamingMinds-DanielC
Copy link
Contributor

GamingMinds-DanielC commented Oct 28, 2024

Instead of setting the hover color to the background color, try setting it to a color with an alpha value of zero. That should disable it,

Edit: not a good solution since it eliminates the highlight from selected selectables if they are hovered. Setting the color based on the current selection state isn't great either as that state can change in the call, introducing a one frame delay for the visualization.

@pbakota
Copy link
Author

pbakota commented Oct 28, 2024

@GamingMinds-DanielC thank you for your comment!

As you noted. Your workaround does remove the highlight indeed, however is also changes the color of selection.

image

It does not give the same visual effect as with my small modification, when I totally skipped over the highlight rendering. I have created this small GIF animation to demonstrate the effect of my "patch". As illustrated by the animation below, when I move the mouse over table rows they do not get highlighted, however when I click on one of them, then it gets highlighted with the proper color of selected items.

output

Here is the part of my code that is rendering a single table row. With your suggested workaround (ImGuiCol_HeaderHovered)

ImGui::PushID(sprite->ID);
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0, 0, 0, 0));
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);

auto oldCursorY = ImGui::GetCursorPosY();
auto flags = ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap | ImGuiSelectableFlags_AllowDoubleClick;
if (ImGui::Selectable("", selectedSpriteId == sprite->ID, flags, ImVec2(0, sprite->h)))
{
    selectedSpriteId = sprite->ID;
}

ImGui::SetCursorPosY(oldCursorY);
ImGui::Image(sprite->GetTexture(renderer), ImVec2(sprite->w, sprite->h));
ImGui::SameLine();

ImGui::Text("%s", sprite->imageName.c_str());

ImGui::TableSetColumnIndex(1);
ImGui::Text("%d; Char %d", 0, row);

ImGui::TableSetColumnIndex(2);
ImGui::Text("%lux%lu pixels,\nByte Order: %s\n%s", sprite->w, sprite->h,
    "Vertical", sprite->multicolor ? "Multicolor" : "");

ImGui::PopStyleColor();
ImGui::PopID();

ocornut added a commit that referenced this issue Oct 28, 2024
… an arbitrary lerp between _Header and _HeaderHovered. (#8106, #1861)
@ocornut
Copy link
Owner

ocornut commented Oct 28, 2024

Indeed it is because the Selection color is currently interpolated:

const bool highlighted = hovered || (flags & ImGuiSelectableFlags_Highlight);
if (highlighted || selected)
{
    // FIXME-MULTISELECT: Styling: Color for 'selected' elements? ImGuiCol_HeaderSelected
    ImU32 col;
    if (selected && !highlighted)
        col = GetColorU32(ImLerp(GetStyleColorVec4(ImGuiCol_Header), GetStyleColorVec4(ImGuiCol_HeaderHovered), 0.5f));
    else
        col = GetColorU32((held && highlighted) ? ImGuiCol_HeaderActive : highlighted ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
    RenderFrame(bb.Min, bb.Max, col, false, 0.0f);
}

I did this as part of 554db6b. I admit I am not sure anymore why: my recollection was that a 4th color was definitively needed and I currently don't want to add too many extra color enums before I redesign the styling system. But right I'm not sure a 4th color is needed: _Header may be used just as well. So I've pushed this change 81cfe09 and it will fix your issue.

(
without my fix you would need to use this workaround:

bool isSelected = selectedSpriteId == sprite->ID;
if (!isSelected)
    ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0, 0, 0, 0));
...
if (!isSelected)
    ImGui::PopStyleColor();

)

@ocornut ocornut closed this as completed Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants