if(!key_data->Down)// Important: ownership is released on the frame after a release. Ensure a 'MouseDown -> CloseWindow -> MouseUp' chain doesn't lead to someone else seeing the MouseUp.
owner_data->OwnerNext=ImGuiKeyOwner_None;
owner_data->LockThisFrame=owner_data->LockUntilRelease=owner_data->LockUntilRelease&&key_data->Down;// Clear LockUntilRelease when key is not Down anymore
// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version for the two users of this function.
if(!key_data->Down)// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on input ownership)
if(!key_data->Down)// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership)
// Important: unlike legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat.
// [Internal] 2022/07: Do not call this directly! It is a temporary entry point which we will soon replace with an overload for IsKeyPressed() when we introduce key ownership.
if(!key_data->Down)// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on input ownership)
if(!key_data->Down)// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership)
returnfalse;
constfloatt=key_data->DownDuration;
if(t<0.0f)
returnfalse;
IM_ASSERT((flags&~ImGuiInputFlags_SupportedByIsKeyPressed)==0);// Passing flags not supported by this function!
returng.IO.MouseDown[button]&&TestKeyOwner(MouseButtonToKey(button),ImGuiKeyOwner_Any);// should be same as IsKeyDown(MouseButtonToKey(button), ImGuiKeyOwner_Any), but this allows legacy code hijacking the io.Mousedown[] array.
returng.IO.MouseDown[button]&&TestKeyOwner(MouseButtonToKey(button),owner_id);// Should be same as IsKeyDown(MouseButtonToKey(button), owner_id), but this allows legacy code hijacking the io.Mousedown[] array.
if(!g.IO.MouseDown[button])// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on input ownership)
if(!g.IO.MouseDown[button])// In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership)
returng.IO.MouseReleased[button]&&TestKeyOwner(MouseButtonToKey(button),ImGuiKeyOwner_Any);// Should be same as IsKeyReleased(MouseButtonToKey(button), ImGuiKeyOwner_Any)
returng.IO.MouseReleased[button]&&TestKeyOwner(MouseButtonToKey(button),owner_id);// Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id)
IM_ASSERT(IsNamedKeyOrModKey(key)&&(owner_id!=ImGuiKeyOwner_Any||(flags&(ImGuiInputFlags_LockThisFrame|ImGuiInputFlags_LockUntilRelease))));// Can only use _Any with _LockXXX flags (to eat a key away without an ID to retrieve it)
IM_ASSERT((flags&~ImGuiInputFlags_SupportedBySetKeyOwner)==0);// Passing flags not supported by this function!
// Extensive uses of that (e.g. many calls for a single item) may want to manually perform the tests once and then call SetKeyOwner() multiple times.
// More advanced usage scenarios may want to call SetKeyOwner() manually based on different condition.
// Worth noting is that only one item can be hovered and only one item can be active, therefore this usage pattern doesn't need to bother with routing and priority.
constboolstart_windowing_with_keyboard=allow_windowing&&!g.NavWindowingTarget&&io.KeyCtrl&&IsKeyPressed(ImGuiKey_Tab,false);// Note: enabled even without NavEnableKeyboard!
constboolstart_windowing_with_keyboard=allow_windowing&&!g.NavWindowingTarget&&(keyboard_next_window||keyboard_prev_window);// Note: enabled even without NavEnableKeyboard!
IM_ASSERT(shared_mods!=0);// Next/Prev shortcut currently needs a shared modifier to "hold", otherwise Prev actions would keep cycling between two windows.
// Keyboard: Press and Release ALT to toggle menu layer
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d",g.HoveredIdPreviousFrame,g.HoveredIdTimer,g.HoveredIdAllowOverlap);// Not displaying g.HoveredId as it is update mid-frame
@ -153,7 +153,7 @@ typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // E
typedefintImGuiLayoutType;// -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedefintImGuiActivateFlags;// -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedefintImGuiDebugLogFlags;// -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
typedefintImGuiInputFlags;// -> enum ImGuiInputFlags_ // Flags: for IsKeyPressedEx()
typedefintImGuiInputFlags;// -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc.
typedefintImGuiItemFlags;// -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags
typedefintImGuiItemStatusFlags;// -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
typedefintImGuiOldColumnFlags;// -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
@ -862,6 +862,8 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_NoHoldingActiveId=1<<17,// don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_NoNavFocus=1<<18,// don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags)
ImGuiButtonFlags_NoHoveredOnFocus=1<<19,// don't report as hovered when nav focus is on this item
ImGuiButtonFlags_NoSetKeyOwner=1<<20,// don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
ImGuiButtonFlags_NoTestKeyOwner=1<<21,// don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
ImGuiSelectableFlags_DrawHoveredWhenHeld=1<<25,// Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow.
ImGuiSelectableFlags_SetNavIdOnHover=1<<26,// Set Nav/Focus ID on mouse hover (used by MenuItem)
ImGuiSelectableFlags_NoPadWithHalfSpacing=1<<27,// Disable padding each side with ItemSpacing * 0.5f
ImGuiSelectableFlags_NoSetKeyOwner=1<<28,// Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
};
// Extend ImGuiTreeNodeFlags_
@ -1291,17 +1294,94 @@ struct ImGuiInputEvent
ImGuiInputEvent(){memset(this,0,sizeof(*this));}
};
// Flags for IsKeyPressedEx(). In upcoming feature this will be used more (and IsKeyPressedEx() renamed)
// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
#define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitely used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
#define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner.
typedefImS16ImGuiKeyRoutingIndex;
// Routing table entry (sizeof() == 16 bytes)
structImGuiKeyRoutingData
{
ImGuiKeyRoutingIndexNextEntryIndex;
ImU16Mods;
ImU8RoutingNextScore;// Lower is better (0: perfect score)
// This extend ImGuiKeyData but only for named keys (legacy keys don't support the new features)
// Stored in main context (1 per named key). In the future might be merged into ImGuiKeyData.
structImGuiKeyOwnerData
{
ImGuiIDOwnerCurr;
ImGuiIDOwnerNext;
boolLockThisFrame;// Reading this key requires explicit owner id (until end of frame). Set by ImGuiInputFlags_LockThisFrame.
boolLockUntilRelease;// Reading this key requires explicit owner id (until key is released). Set by ImGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well.
// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner()
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
enumImGuiInputFlags_
{
// Flags for IsKeyPressedEx()
// Flags for IsKeyPressed(), IsMouseClicked(), Shortcut()
ImGuiInputFlags_None=0,
ImGuiInputFlags_Repeat=1<<0,// Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
ImGuiInputFlags_LockThisFrame=1<<6,// Access to key data will requires EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
ImGuiInputFlags_LockUntilRelease=1<<7,// Access to key data will requires EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when key is released or at end of frame is not down. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
// Routing policies for Shortcut() + low-level SetShortcutRouting()
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
// - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(),
// allowing the system to decide where to route the input among other route-aware calls.
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll
// will register a route and only succeed when parent window is in the focus stack and if no-one
// with a higher priority is claiming the shortcut.
// - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods.
// - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow.
// - Can select only 1 policy among all available.
ImGuiInputFlags_RouteFocused=1<<8,// (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
ImGuiInputFlags_RouteGlobalLow=1<<9,// Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
ImGuiInputFlags_RouteGlobal=1<<10,// Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
ImGuiInputFlags_RouteGlobalHigh=1<<11,// Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
ImGuiInputFlags_RouteMask_=ImGuiInputFlags_RouteFocused|ImGuiInputFlags_RouteGlobal|ImGuiInputFlags_RouteGlobalLow|ImGuiInputFlags_RouteGlobalHigh,// _Always not part of this!
ImGuiInputFlags_RouteAlways=1<<12,// Do not register route, poll keys directly.
ImGuiInputFlags_RouteUnlessBgFocused=1<<13,// Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
ImGuiIDHoveredId;// Hovered widget, filled during the frame
ImGuiIDHoveredIdPreviousFrame;
boolHoveredIdAllowOverlap;
boolHoveredIdUsingMouseWheel;// Hovered widget will use mouse wheel. Blocks scrolling the underlying window.
boolHoveredIdPreviousFrameUsingMouseWheel;
boolHoveredIdDisabled;// At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
floatHoveredIdTimer;// Measure contiguous hovering time
floatHoveredIdNotActiveTimer;// Measure contiguous hovering time where the item has not been active
@ -1863,9 +1941,14 @@ struct ImGuiContext
ImGuiIDLastActiveId;// Store the last non-zero ActiveId, useful for animation.
floatLastActiveIdTimer;// Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
// Input Ownership
// [EXPERIMENTAL] Key/Input Ownership + Shortcut Routing system
// - The idea is that instead of "eating" a given key, we can link to an owner.
// - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
// - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame().
ImU32ActiveIdUsingNavDirMask;// Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
ImBitArrayForNamedKeysActiveIdUsingKeyInputMask;// Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array.
boolActiveIdUsingAllKeyboardKeys;// Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency)
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
ImU32ActiveIdUsingNavInputMask;// If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetActiveIdUsingKey(ImGuiKey_Escape); SetActiveIdUsingKey(ImGuiKey_NavGamepadCancel);'
#endif
@ -1946,6 +2029,8 @@ struct ImGuiContext
ImGuiNavItemDataNavTabbingResultFirst;// First tabbing request candidate within NavWindow and flattened hierarchy
// Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
ImGuiKeyChordConfigNavWindowingKeyNext;// = ImGuiMod_Ctrl | ImGuiKey_Tab, for reconfiguration (see #4828)
ImGuiWindow*NavWindowingTarget;// Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
ImGuiWindow*NavWindowingTargetAnim;// Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it.
ImGuiWindow*NavWindowingListWindow;// Internal window actually listing the CTRL+Tab contents
// - The idea is that instead of "eating" a given input, we can link to an owner.
// - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead).
// - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
// - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0).
// - Input ownership is automatically released on the frame after a key is released. Therefore:
// - for ownership registration happening a result of a down/press event, the SetKeyOwner() call may be done once (common case).
// - for ownership registration happening ahead of a down/press event, the SetKeyOwner() call needs to be made every frame (happens if e.g. claiming ownership on hover).
// - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state.
// - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step.
// Please open a GitHub Issue to submit your usage scenario or if there's a use case you need solved.
IMGUI_APIvoidSetItemKeyOwner(ImGuiKeykey,ImGuiInputFlagsflags=0);// Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
IMGUI_APIboolTestKeyOwner(ImGuiKeykey,ImGuiIDowner_id);// Test that key is either not owned, either owned by 'owner_id'
// [EXPERIMENTAL] High-Level: Input Access functions w/ support for Key/Input Ownership
// - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag.
// - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0)
// - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'.
// Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitely used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
// - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API.
IMGUI_APIboolIsKeyPressed(ImGuiKeykey,ImGuiIDowner_id,ImGuiInputFlagsflags=0);// Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat.
// - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.
// ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord)
// ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord)
// ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values.
// - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy.
// - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame.
// - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
// - Multiple read sites may use a same owner and will all get the granted route.
// - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
// (some functions are only declared in imgui.cpp, see Docking section)
@ -3284,6 +3408,7 @@ namespace ImGui
// Obsolete functions
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inlinevoidSetItemUsingMouseWheel(){SetItemKeyOwner(ImGuiKey_MouseWheelY);}// Changed in 1.89
inlineboolTreeNodeBehaviorIsOpen(ImGuiIDid,ImGuiTreeNodeFlagsflags=0){returnTreeNodeUpdateNextOpen(id,flags);}// Renamed in 1.89
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
@ -3294,6 +3419,9 @@ namespace ImGui
inlineboolFocusableItemRegister(ImGuiWindow*window,ImGuiIDid){IM_ASSERT(0);IM_UNUSED(window);IM_UNUSED(id);returnfalse;}// -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
inlineboolIsKeyPressedMap(ImGuiKeykey,boolrepeat=true){IM_ASSERT(IsNamedKey(key));returnIsKeyPressed(key,repeat);}// Removed in 1.87: Mapping from named key is always identity!
// Using Shortcut() with ImGuiInputFlags_RouteFocused flag to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText)
// Otherwise we could simply assume that we own the keys as we are active.
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.