Skip to content

Commit

Permalink
Shortcuts: added ImGuiInputFlags_RouteActiveItem. (#456, #7618) + rea…
Browse files Browse the repository at this point in the history
…rrange Changelog
  • Loading branch information
ocornut committed May 24, 2024
1 parent 16b72f2 commit ef9d525
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 32 deletions.
43 changes: 26 additions & 17 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,37 @@ Other changes:
- Windows: BeginChild(): fixed auto-fit calculation when using either (not both) ResizeX/ResizeY
and double-clicking on a border. Calculation incorrectly didn't always account for scrollbar as
it assumed the other axis would also be auto-fit. (#1710)
- Inputs: added Shortcut() function (w/ routing policies) in public API. (#456, #2637)
- using ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy:
- checks that CTRL+C is pressed,
- and that current window is in focus stack,
- and that no other requests for CTRL+C have been made from deeper locations of the window/item stack.
- Added ImGuiInputFlags_RouteFocused, ImGuiInputFlags_RouteGlobal and other flags
related to routing policies. (#456, #2637)
- Added ImGuiInputFlags_Repeat for use by Shortcut() and by upcoming (still internal)
extended rework of various input functions.
- About routing system and routing policies:
The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
- Inputs: added shortcut and routing system in public API. (#456, #2637)
- The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts)
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 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.
- Added Shortcut() function:
e.g. Using ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy:
- checks that CTRL+C is pressed,
- and that current window is in focus stack,
- and that no other requests for CTRL+C have been made from higher priority locations
(e.g. deeper in the window/item stack).
- Added SetNextItemShortcut() to set a shortcut to locally or remotely press or activate
an item (depending on specified routing policy: using ImGuiInputFlags_RouteGlobal the item
shortcut may be executed even if its window is not in focus stack).
Items like buttons are not fully activated, in the sense that they get pressed but another
active item, e.g. InputText() won't be deactivated.
- Added routing policies for Shortcut(), SetNextItemShortcut(): (#456, #2637)
- ImGuiInputFlags_RouteFocused: focus stack route (default)
- ImGuiInputFlags_RouteActiveItem: only route to active item
- ImGuiInputFlags_RouteGlobal: route globally, unless a focus route claim shame shortcut.
- ImGuiInputFlags_RouteGlobalOverFocused
- ImGuiInputFlags_RouteGlobalHighest
- ImGuiInputFlags_RouteAlways: no routing submission, no routing check.
- Added other shortcut/routing options: (#456, #2637)
- ImGuiInputFlags_Repeat: for use by Shortcut() and by upcoming rework of various
input functions (which are still internal for now).
- ImGuiInputFlags_Tooltip: for SetNextItemShortcut() to show a tooltip when hovering item.
- ImGuiInputFlags_RouteUnlessBgFocused
- ImGuiInputFlags_RouteFromRootWindow
- 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)
Expand Down
20 changes: 14 additions & 6 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8605,18 +8605,17 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)

// Current score encoding (lower is highest priority):
// - 0: ImGuiInputFlags_RouteGlobalHighest
// - 1: ImGuiInputFlags_RouteFocused (if item active)
// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active)
// - 2: ImGuiInputFlags_RouteGlobalOverFocused
// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack)
// - 254: ImGuiInputFlags_RouteGlobal
// - 255: never route
// 'flags' should include an explicit routing policy
static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags)
{
ImGuiContext& g = *GImGui;
if (flags & ImGuiInputFlags_RouteFocused)
{
ImGuiContext& g = *GImGui;

// ActiveID gets top priority
// (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it)
if (owner_id != 0 && g.ActiveId == owner_id)
Expand All @@ -8637,12 +8636,18 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput

return 255;
}

// ImGuiInputFlags_RouteGlobalHighest is default, so calls without flags are not conditional
if (flags & ImGuiInputFlags_RouteActiveItem)
{
if (owner_id != 0 && g.ActiveId == owner_id)
return 1;
return 255;
}
if (flags & ImGuiInputFlags_RouteGlobalOverFocused)
return 2;
if (flags & ImGuiInputFlags_RouteGlobal)
return 254;

// ImGuiInputFlags_RouteGlobalHighest is default, so calls without flags are not conditional
return 0;
}

Expand Down Expand Up @@ -8693,7 +8698,7 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
return true;
}

// Specific culling when there's an active.
// Specific culling when there's an active item.
if (g.ActiveId != 0 && g.ActiveId != owner_id)
{
// Cull shortcuts with no modifiers when it could generate a character.
Expand All @@ -8707,6 +8712,9 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
return false;
}

if (flags & ImGuiInputFlags_RouteActiveItem)
return false;

// ActiveIdUsingAllKeyboardKeys trumps all for ActiveId
if ((flags & ImGuiInputFlags_RouteGlobalHighest) == 0 && g.ActiveIdUsingAllKeyboardKeys)
{
Expand Down
17 changes: 9 additions & 8 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -1483,17 +1483,18 @@ enum ImGuiInputFlags_

// 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.
// - Priorities: RouteGlobalHighest >> RouteActiveItem or RouteFocused (if owner is active item) >> RouteGlobalOverFocused >> RouteFocused (if in focused window stack) >> RouteGlobal.
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.
ImGuiInputFlags_RouteGlobal = 1 << 13, // Global route (normal priority): unless a focused window or active item registered the route) -> recommended Global priority.
ImGuiInputFlags_RouteGlobalOverFocused = 1 << 14, // Global route (higher priority): unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this).
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: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
ImGuiInputFlags_RouteFromRootWindow = 1 << 18, // Option: route evaluated from the point of view of root window rather than current window.
ImGuiInputFlags_RouteActiveItem = 1 << 13, // Route to active item only.
ImGuiInputFlags_RouteGlobal = 1 << 14, // Global route (normal priority): unless a focused window or active item registered the route) -> recommended Global priority.
ImGuiInputFlags_RouteGlobalOverFocused = 1 << 15, // Global route (higher priority): unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this.
ImGuiInputFlags_RouteGlobalHighest = 1 << 16, // 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. May not be fully honored as user/internal code is likely to always assume they can access keys when active.
ImGuiInputFlags_RouteAlways = 1 << 17, // Do not register route, poll keys directly.
ImGuiInputFlags_RouteUnlessBgFocused = 1 << 18, // Option: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
ImGuiInputFlags_RouteFromRootWindow = 1 << 19, // Option: route evaluated from the point of view of root window rather than current window.

// Flags for SetNextItemShortcut()
ImGuiInputFlags_Tooltip = 1 << 19, // Automatically display a tooltip when hovering item.
ImGuiInputFlags_Tooltip = 1 << 20, // Automatically display a tooltip when hovering item.
};

#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
Expand Down
1 change: 1 addition & 0 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6283,6 +6283,7 @@ static void ShowDemoWindowInputs()
static ImGuiInputFlags routing_flags = ImGuiInputFlags_RouteFocused;
ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &other_flags, ImGuiInputFlags_Repeat);
ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &routing_flags, ImGuiInputFlags_RouteFocused);
ImGui::RadioButton("ImGuiInputFlags_RouteActiveItem", &routing_flags, ImGuiInputFlags_RouteActiveItem);
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &routing_flags, ImGuiInputFlags_RouteAlways);
ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &routing_flags, ImGuiInputFlags_RouteGlobal);
ImGui::RadioButton("ImGuiInputFlags_RouteGlobalOverFocused", &routing_flags, ImGuiInputFlags_RouteGlobalOverFocused);
Expand Down
2 changes: 1 addition & 1 deletion imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ enum ImGuiInputFlagsPrivate_
ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress,
ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_,
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobalOverFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalHighest | ImGuiInputFlags_RouteAlways,
ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteActiveItem | ImGuiInputFlags_RouteGlobalOverFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalHighest | ImGuiInputFlags_RouteAlways,
ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow,
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_,
ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat,
Expand Down

0 comments on commit ef9d525

Please sign in to comment.