- Added SetKeyOwner(), SetItemKeyOwner(), TestKeyOwner().
- Added new IsKeyXXX IsMouseXXX functions with ImGuID owner_id and flags.
- Obsoleted SetItemUsingMouseWheel(). (#2891)
- Removed IsKeyPresseedEx() which was a recent internal addition 2022-07-08 deemed to be temporary exactly for this.
- Added ImGuiButtonFlags_NoSetKeyOwner, ImGuiButtonFlags_NoTestKeyOwner
- Added ImGuiSelectableFlags_NoSetKeyOwner.
- Added ImGuiInputFlags_LockThisFrame, ImGuiInputFlags_LockUntilRelease for for SetKeyOwner(), SetItemKeyOwner().
- Added ImGuiInputFlags_CondXXX values for SetItemKeyOwner().
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)
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)
// 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&&io.KeyCtrl&&IsKeyPressed(ImGuiKey_Tab,ImGuiKeyOwner_None);// Note: enabled even without NavEnableKeyboard!
// 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
@ -148,7 +148,7 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
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()
@ -852,6 +852,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_
@ -1270,17 +1273,43 @@ 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.
// 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(), SetKeyOwner(), SetItemKeyOwner()
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
enumImGuiInputFlags_
{
// Flags for IsKeyPressedEx()
// Flags for IsKeyPressed(), IsMouseClicked()
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.
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
@ -1680,9 +1707,12 @@ 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
// - 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.
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);'
// - 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.
// This is generally used to identify a unique input location (for e.g. a selection set)
@ -2988,6 +3040,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():
@ -2998,6 +3051,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!