From c06e6340cdefaf278fce217acae829f0589f53fb Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 23 May 2024 16:39:39 +0200 Subject: [PATCH] Shortcuts: added ImGuiInputFlags_Tooltip. (#456) --- docs/CHANGELOG.txt | 7 ++++++- imgui.cpp | 14 +++++++++++++- imgui.h | 5 ++++- imgui_demo.cpp | 14 +++++++------- imgui_internal.h | 11 +++++++---- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 567c1d801..0a3263e6f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -72,7 +72,12 @@ Other changes: Child2 -> no call // When Child2 is focused, Parent gets the shortcut. The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical. This is an important property as it facilitate working with foreign code or larger codebase. -- Inputs: added SetNextItemShortcut() to set a shortcut to activate an item. (#456) +- Inputs: added SetNextItemShortcut() to set a shortcut to locally or remotely press or activate + an item (depending on specified routing policy). Items like buttons are not fully activated, in + the sense that they get pressed but an active e.g. InputText() won't be deactivated. (#456) + - Added ImGuiInputFlags_Tooltip to automatically show a tooltip when hovering item. + - Using e.g. ImGuiInputFlags_RouteGlobal the item shortcut may be executed even if its + window is not in focus stack. - Inputs: (OSX) Fixes variety of code which inconsistently required using Ctrl instead of Cmd. - e.g. Drags/Sliders now use Cmd+Click to input a value. (#4084) - Some shortcuts still uses Ctrl on Mac: e.g. Ctrl+Tab to switch windows. (#4828) diff --git a/imgui.cpp b/imgui.cpp index 20a36d6e0..9b74f097f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4186,6 +4186,11 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag if (g.HoveredIdPreviousFrame != id) return false; } + + // Display shortcut (only works with mouse) + if (id == g.LastItemData.ID && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasShortcut)) + if (IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_DelayNormal)) + SetTooltip("%s", GetKeyChordName(g.LastItemData.Shortcut)); } // When disabled we'll return false but still set HoveredId @@ -10020,7 +10025,14 @@ void ImGui::ItemHandleShortcut(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiInputFlags flags = g.NextItemData.ShortcutFlags; - if (!Shortcut(g.NextItemData.Shortcut, flags, id) || g.NavActivateId != 0) + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetNextItemShortcut) == 0); // Passing flags not supported by SetNextItemShortcut()! + + if (flags & ImGuiInputFlags_Tooltip) + { + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasShortcut; + g.LastItemData.Shortcut = g.NextItemData.Shortcut; + } + if (!Shortcut(g.NextItemData.Shortcut, flags & ImGuiInputFlags_SupportedByShortcut, id) || g.NavActivateId != 0) return; // FIXME: Generalize Activation queue? diff --git a/imgui.h b/imgui.h index c0152ff30..a47af9e6e 100644 --- a/imgui.h +++ b/imgui.h @@ -1481,7 +1481,7 @@ enum ImGuiInputFlags_ ImGuiInputFlags_None = 0, ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. - // Flags for Shortcut() + // Flags for Shortcut(), SetNextItemShortcut() // - Default policy is RouteFocused. Can select only 1 policy among all available. // - Priorities: GlobalHighest > Focused (if owner is active item) > GlobalOverFocused > Focused (if in focused window) > Global. ImGuiInputFlags_RouteFocused = 1 << 12, // Focus stack route (default): Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. @@ -1490,6 +1490,9 @@ enum ImGuiInputFlags_ ImGuiInputFlags_RouteGlobalHighest = 1 << 15, // Global route (highest priority): unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this) ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly. ImGuiInputFlags_RouteUnlessBgFocused = 1 << 17, // Option combine with others: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + + // Flags for SetNextItemShortcut() + ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item. }; #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d9ce610d3..cc8192150 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7206,7 +7206,7 @@ struct ExampleAppConsole } // Options, Filter - ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O); // FIXME + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O, ImGuiInputFlags_Tooltip); if (ImGui::Button("Options")) ImGui::OpenPopup("Options"); ImGui::SameLine(); @@ -8437,16 +8437,16 @@ struct MyDocument ImGui::PushStyleColor(ImGuiCol_Text, doc->Color); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); ImGui::PopStyleColor(); - ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M); - if (ImGui::Button("Modify (Ctrl+M)")) + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Modify")) doc->Dirty = true; ImGui::SameLine(); - ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S); - if (ImGui::Button("Save (Ctrl+S)")) + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Save")) doc->DoSave(); ImGui::SameLine(); - ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W); - if (ImGui::Button("Close (Ctrl+W)")) + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Close")) doc->DoQueueClose(); ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior. ImGui::PopID(); diff --git a/imgui_internal.h b/imgui_internal.h index fa65dae87..fa8f2c97d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -841,7 +841,8 @@ enum ImGuiItemStatusFlags_ ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. ImGuiItemStatusFlags_Visible = 1 << 8, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()). - ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid + ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid. + ImGuiItemStatusFlags_HasShortcut = 1 << 10, // g.LastItemData.Shortcut valid. Set by SetNextItemShortcut() -> ItemAdd(). // Additional status + semantic for ImGuiTestEngine #ifdef IMGUI_ENABLE_TEST_ENGINE @@ -1202,9 +1203,10 @@ struct ImGuiLastItemData ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ ImRect Rect; // Full rectangle ImRect NavRect; // Navigation scoring rectangle (not displayed) - // Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags is set. - ImRect DisplayRect; // Display rectangle (ONLY VALID IF ImGuiItemStatusFlags_HasDisplayRect is set) - ImRect ClipRect; // Clip rectangle at the time of submitting item (ONLY VALID IF ImGuiItemStatusFlags_HasClipRect is set) + // Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set. + ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set. + ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set.. + ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set.. ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } }; @@ -1479,6 +1481,7 @@ enum ImGuiInputFlagsPrivate_ ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_, ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat, ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteUnlessBgFocused, + ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_Tooltip, ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, };