mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	- and ImGuiInputFlags_RouteUnlessBgFocused - will be useful for blind menu handlers.
This commit is contained in:
		
							
								
								
									
										50
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -8052,11 +8052,24 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) | |||||||
| bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags, ImGuiWindow* location) | bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags, ImGuiWindow* location) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |     if ((flags & ImGuiInputFlags_RouteMask_) == 0) | ||||||
|  |         flags = ImGuiInputFlags_RouteGlobalHigh; // This is the default for SetShortcutRouting() but NOT Shortcut() which doesn't touch routing by default! | ||||||
|  |     else | ||||||
|  |         IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used | ||||||
|     IM_ASSERT(owner_id != ImGuiKeyOwner_None); |     IM_ASSERT(owner_id != ImGuiKeyOwner_None); | ||||||
|  |  | ||||||
|     // Calculate our score |     if (flags & ImGuiInputFlags_RouteUnlessBgFocused) | ||||||
|  |         if (g.NavWindow == NULL) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |     // Current score encoding (lower is highest priority): | ||||||
|  |     //  -   0: ImGuiInputFlags_RouteGlobalHigh | ||||||
|  |     //  -   1: ImGuiInputFlags_RouteFocused (if item active) | ||||||
|  |     //  -   2: ImGuiInputFlags_RouteGlobal | ||||||
|  |     //  -  3+: ImGuiInputFlags_RouteFocused (if window in focus-stack) | ||||||
|  |     //  - 254: ImGuiInputFlags_RouteGlobalLow | ||||||
|  |     //  - 255: none | ||||||
|     int score = 255; |     int score = 255; | ||||||
|     bool always_set_next_route = false; |  | ||||||
|     if (flags & ImGuiInputFlags_RouteFocused) |     if (flags & ImGuiInputFlags_RouteFocused) | ||||||
|     { |     { | ||||||
|         if (location == NULL) |         if (location == NULL) | ||||||
| @@ -8065,44 +8078,48 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI | |||||||
|  |  | ||||||
|         if (g.ActiveId != 0 && g.ActiveId == owner_id) |         if (g.ActiveId != 0 && g.ActiveId == owner_id) | ||||||
|         { |         { | ||||||
|             // ActiveID gets top priority (0) |             // 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) |             // (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it) | ||||||
|             score = 0; |             score = 1; | ||||||
|         } |         } | ||||||
|         else if (focused != NULL && focused->RootWindow == location->RootWindow) // Early out |         else if (focused != NULL && focused->RootWindow == location->RootWindow) // Early out | ||||||
|         { |         { | ||||||
|             // Score based on distance to focused window (lower is better) |             // Score based on distance to focused window (lower is better) | ||||||
|             // Assuming both windows are submitting a routing request, |             // Assuming both windows are submitting a routing request, | ||||||
|             // - When WindowA...... is focused -> WindowA scores 1 (best), WindowA/ChildB scores 255 (no match) |             // - When Window....... is focused -> Window scores 3 (best), Window/ChildB scores 255 (no match) | ||||||
|             // - When Window/ChildB is focused -> WindowA scores 2,        WindowA/ChildB scores 1 (best) |             // - When Window/ChildB is focused -> Window scores 4,        Window/ChildB scores 3 (best) | ||||||
|             // Assuming only WindowA is submitting a routing request, |             // Assuming only WindowA is submitting a routing request, | ||||||
|             // - When Window/ChildB is focused -> WindowA scores 2 (best), WindowA/ChildB doesn't have a scoe. |             // - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score. | ||||||
|             for (int next_score = 1; focused != NULL; next_score++) |             for (int next_score = 3; focused != NULL; next_score++) | ||||||
|             { |             { | ||||||
|                 if (focused == location) |                 if (focused == location) | ||||||
|                 { |                 { | ||||||
|  |                     IM_ASSERT(next_score < 255); | ||||||
|                     score = (ImU8)next_score; |                     score = (ImU8)next_score; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|                 focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path |                 focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (score == 255) |  | ||||||
|             return false; |  | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         score = 0; |         if (flags & ImGuiInputFlags_RouteGlobal) | ||||||
|         always_set_next_route = true; |             score = 2; | ||||||
|  |         else if (flags & ImGuiInputFlags_RouteGlobalLow) | ||||||
|  |             score = 254; | ||||||
|  |         else // ImGuiInputFlags_RouteGlobalHigh is default, so call to SetShorcutRouting() without no flags are not conditional | ||||||
|  |             score = 0; | ||||||
|     } |     } | ||||||
|  |     if (score == 255) | ||||||
|  |         return false; | ||||||
|  |  | ||||||
|     // Submit routing for NEXT frame (assuming score is sufficient) |     // Submit routing for NEXT frame (assuming score is sufficient) | ||||||
|     // FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <). |     // FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <). | ||||||
|     ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); |     ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); | ||||||
|     const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); // FIXME: Location |     const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); // FIXME: Location | ||||||
|     //const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore); |     //const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore); | ||||||
|     if (score < routing_data->RoutingNextScore || always_set_next_route) |     if (score < routing_data->RoutingNextScore) | ||||||
|     { |     { | ||||||
|         routing_data->RoutingNext = routing_id; |         routing_data->RoutingNext = routing_id; | ||||||
|         routing_data->RoutingNextScore = (ImU8)score; |         routing_data->RoutingNextScore = (ImU8)score; | ||||||
| @@ -8598,8 +8615,9 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags | |||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |  | ||||||
|     if (flags & ImGuiInputFlags_RouteFocused) |     // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter  with this, so IsKeyPressed() is fine with he 0/Any. | ||||||
|         if (!SetShortcutRouting(key_chord, owner_id, ImGuiInputFlags_RouteFocused, g.CurrentWindow)) |     if (flags & (ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteUnlessBgFocused)) | ||||||
|  |         if (!SetShortcutRouting(key_chord, owner_id, flags, g.CurrentWindow)) | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|     ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); |     ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); | ||||||
|   | |||||||
| @@ -1337,13 +1337,25 @@ enum ImGuiInputFlags_ | |||||||
|     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_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. |     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. | ||||||
|  |  | ||||||
|     // Flags for Shortcut(), SetShortcutRouting() |     // Routing policies for Shortcut(), SetShortcutRouting() | ||||||
|     // When Focus Routing is enabled, function will call SetShortcutRouting(): Accept inputs if currently in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. |     // - When a policy is set, Shortcut() will register itself with SetShortcutRouting(), | ||||||
|     ImGuiInputFlags_RouteFocused        = 1 << 8,   // Enable focus routing |     //   allowing the system to decide where to route the input among other route-aware calls. | ||||||
|  |     //   The general idea is that several callers register a shortcut, and only one gets it. | ||||||
|  |     // - Routing is NOT registered by default, meaning that a simple Shortcut() call | ||||||
|  |     //   will see all inputs, won't have any side-effect and won't interfere with other inputs. | ||||||
|  |     // - Priorities (highest-to-lowest): GlobalHigh > Focused (when active item) > Global > Focused (when focused window) > GlobalLow. | ||||||
|  |     // - Can select only 1 policy among all available. | ||||||
|  |     ImGuiInputFlags_RouteNone           = 0,        // Do not register route (provided for completeness but technically zero-value) | ||||||
|  |     ImGuiInputFlags_RouteFocused        = 1 << 8,   // Register route if focused: 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, | ||||||
|  |     ImGuiInputFlags_RouteUnlessBgFocused= 1 << 12,  // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. | ||||||
|  |  | ||||||
|     // [Internal] Mask of which function support which flags |     // [Internal] Mask of which function support which flags | ||||||
|     ImGuiInputFlags_SupportedByIsKeyPressed     = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_, |     ImGuiInputFlags_SupportedByIsKeyPressed     = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_, | ||||||
|     ImGuiInputFlags_SupportedByShortcut         = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteFocused, |     ImGuiInputFlags_SupportedByShortcut         = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteUnlessBgFocused, | ||||||
|     ImGuiInputFlags_SupportedBySetKeyOwner      = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, |     ImGuiInputFlags_SupportedBySetKeyOwner      = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, | ||||||
|     ImGuiInputFlags_SupportedBySetItemKeyOwner  = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, |     ImGuiInputFlags_SupportedBySetItemKeyOwner  = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -4290,7 +4290,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ | |||||||
|         const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl;                     // OS X style: Text editing cursor movement using Alt instead of Ctrl |         const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl;                     // OS X style: Text editing cursor movement using Alt instead of Ctrl | ||||||
|         const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt;  // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End |         const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt;  // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End | ||||||
|  |  | ||||||
|         // Using Shortcut() with ImGuiInputFlags_FocusRouting 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) |         // 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. |         // Otherwise we could simply assume that we own the keys as we are active. | ||||||
|         const ImGuiInputFlags shortcut_flags = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_Repeat; |         const ImGuiInputFlags shortcut_flags = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_Repeat; | ||||||
|         const bool is_cut   = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, shortcut_flags) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, shortcut_flags)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); |         const bool is_cut   = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, shortcut_flags) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, shortcut_flags)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user