From c7b925609777aec45326791c5105a433b3e4e3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20H=C3=A9rilier?= Date: Fri, 26 Jul 2024 13:19:22 +0200 Subject: [PATCH] Selectable: added ImGuiSelectableFlags_Highlight flag to highlight items independently from the hovered state. (#7820) Demo: Make the Widget/List boxes show how to use forced highlighting. --- docs/CHANGELOG.txt | 2 ++ imgui.h | 1 + imgui_demo.cpp | 33 +++++++++++++++++++++------------ imgui_widgets.cpp | 7 ++++--- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index dca2d3259..2ac60cd72 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -147,6 +147,8 @@ Other changes: - Nav: fixed clicking window decorations (e.g. resize borders) from losing focused item when within a child window using ImGuiChildFlags_NavFlattened. - InputText: added '\' and '/' as word seperator. (#7824, #7704) [@reduf] +- Selectable: added ImGuiSelectableFlags_Highlight flag to highlight items independently from + the hovered state. (#7820) [@rerilier] - Clipper: added SeekCursorForItem() function. When using ImGuiListClipper::Begin(INT_MAX) you can can use the clipper without knowing the amount of items beforehand. (#1311) In this situation, call ImGuiListClipper::SeekCursorForItem(items_count) as the end of your iteration diff --git a/imgui.h b/imgui.h index db9e59dad..de7a4d2bc 100644 --- a/imgui.h +++ b/imgui.h @@ -1228,6 +1228,7 @@ enum ImGuiSelectableFlags_ ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too ImGuiSelectableFlags_Disabled = 1 << 3, // Cannot be selected, display grayed out text ImGuiSelectableFlags_AllowOverlap = 1 << 4, // (WIP) Hit testing to allow subsequent widgets to overlap this one + ImGuiSelectableFlags_Highlight = 1 << 5, // Make the item be displayed as if it is hovered #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS ImGuiSelectableFlags_DontClosePopups = ImGuiSelectableFlags_NoAutoClosePopups, // Renamed in 1.91.0 diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8684bd0c6..0c61352d7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1357,18 +1357,18 @@ static void ShowDemoWindowWidgets(DemoWindowData* demo_data) // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively // stored in the object itself, etc.) const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; - static int item_current_idx = 0; // Here we store our selection data as an index. + static int item_selected_idx = 0; // Here we store our selection data as an index. // Pass in the preview value visible before opening the combo (it could technically be different contents or not pulled from items[]) - const char* combo_preview_value = items[item_current_idx]; + const char* combo_preview_value = items[item_selected_idx]; if (ImGui::BeginCombo("combo 1", combo_preview_value, flags)) { for (int n = 0; n < IM_ARRAYSIZE(items); n++) { - const bool is_selected = (item_current_idx == n); + const bool is_selected = (item_selected_idx == n); if (ImGui::Selectable(items[n], is_selected)) - item_current_idx = n; + item_selected_idx = n; // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) if (is_selected) @@ -1410,14 +1410,22 @@ static void ShowDemoWindowWidgets(DemoWindowData* demo_data) // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively // stored in the object itself, etc.) const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; - static int item_current_idx = 0; // Here we store our selection data as an index. + static int item_selected_idx = 0; // Here we store our selected data as an index. + + static bool item_highlight = false; + int item_highlighted_idx = -1; // Here we store our highlighted data as an index. + ImGui::Checkbox("Highlight hovered item in second listbox", &item_highlight); + if (ImGui::BeginListBox("listbox 1")) { for (int n = 0; n < IM_ARRAYSIZE(items); n++) { - const bool is_selected = (item_current_idx == n); + const bool is_selected = (item_selected_idx == n); if (ImGui::Selectable(items[n], is_selected)) - item_current_idx = n; + item_selected_idx = n; + + if (item_highlight && ImGui::IsItemHovered()) + item_highlighted_idx = n; // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) if (is_selected) @@ -1433,9 +1441,10 @@ static void ShowDemoWindowWidgets(DemoWindowData* demo_data) { for (int n = 0; n < IM_ARRAYSIZE(items); n++) { - const bool is_selected = (item_current_idx == n); - if (ImGui::Selectable(items[n], is_selected)) - item_current_idx = n; + bool is_selected = (item_selected_idx == n); + ImGuiSelectableFlags flags = (item_highlighted_idx == n) ? ImGuiSelectableFlags_Highlight : 0; + if (ImGui::Selectable(items[n], is_selected, flags)) + item_selected_idx = n; // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) if (is_selected) @@ -1482,8 +1491,8 @@ static void ShowDemoWindowWidgets(DemoWindowData* demo_data) ImGui::TreePop(); } - IMGUI_DEMO_MARKER("Widgets/Selectables/In columns"); - if (ImGui::TreeNode("In columns")) + IMGUI_DEMO_MARKER("Widgets/Selectables/In Tables"); + if (ImGui::TreeNode("In Tables")) { static bool selected[10] = {}; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index b1ee63ce5..31ba7d5c7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6894,14 +6894,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // Render if (is_visible) { - if (hovered || selected) + const bool highlighted = hovered || (flags & ImGuiSelectableFlags_Highlight); + if (highlighted || selected) { // FIXME-MULTISELECT: Styling: Color for 'selected' elements? ImGuiCol_HeaderSelected ImU32 col; - if (selected && !hovered) + if (selected && !highlighted) col = GetColorU32(ImLerp(GetStyleColorVec4(ImGuiCol_Header), GetStyleColorVec4(ImGuiCol_HeaderHovered), 0.5f)); else - col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + col = GetColorU32((held && highlighted) ? ImGuiCol_HeaderActive : highlighted ? ImGuiCol_HeaderHovered : ImGuiCol_Header); RenderFrame(bb.Min, bb.Max, col, false, 0.0f); } if (g.NavId == id)