mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Nav: Tabbing now cycles through all items when ImGuiConfigFlags_NavEnableKeyboard is set. (#3092, #5759, #787)
This commit is contained in:
		| @@ -53,6 +53,10 @@ Breaking Changes: | |||||||
|  |  | ||||||
| Other changes: | Other changes: | ||||||
|  |  | ||||||
|  | - Nav: Tabbing now cycles through all items when ImGuiConfigFlags_NavEnableKeyboard is set. | ||||||
|  |   (#3092, #5759, #787) | ||||||
|  | - Nav: Tabbing/Shift-Tabbing can more reliably be used to step out of an item that is not | ||||||
|  |   tab-stoppable. (#3092, #5759, #787) | ||||||
| - Nav: Made Enter key submit the same type of Activation event as Space key, | - Nav: Made Enter key submit the same type of Activation event as Space key, | ||||||
|   allowing to press buttons with Enter. (#5606) |   allowing to press buttons with Enter. (#5606) | ||||||
|   (Enter emulates a "prefer text input" activation vs. |   (Enter emulates a "prefer text input" activation vs. | ||||||
|   | |||||||
							
								
								
									
										170
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -39,14 +39,13 @@ Index of this file: | |||||||
| DOCUMENTATION | DOCUMENTATION | ||||||
|  |  | ||||||
| - MISSION STATEMENT | - MISSION STATEMENT | ||||||
| - END-USER GUIDE | - CONTROLS GUIDE | ||||||
| - PROGRAMMER GUIDE | - PROGRAMMER GUIDE | ||||||
|   - READ FIRST |   - READ FIRST | ||||||
|   - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI |   - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI | ||||||
|   - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE |   - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE | ||||||
|   - HOW A SIMPLE APPLICATION MAY LOOK LIKE |   - HOW A SIMPLE APPLICATION MAY LOOK LIKE | ||||||
|   - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE |   - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE | ||||||
|   - USING KEYBOARD/GAMEPAD NAVIGATION CONTROLS |  | ||||||
| - API BREAKING CHANGES (read me when you update!) | - API BREAKING CHANGES (read me when you update!) | ||||||
| - FREQUENTLY ASKED QUESTIONS (FAQ) | - FREQUENTLY ASKED QUESTIONS (FAQ) | ||||||
|   - Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer) |   - Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer) | ||||||
| @@ -114,27 +113,73 @@ CODE | |||||||
|  - Limited layout features, intricate layouts are typically crafted in code. |  - Limited layout features, intricate layouts are typically crafted in code. | ||||||
|  |  | ||||||
|  |  | ||||||
|  END-USER GUIDE |  CONTROLS GUIDE | ||||||
|  ============== |  ============== | ||||||
|  |  | ||||||
|  - Double-click on title bar to collapse window. |  - MOUSE CONTROLS | ||||||
|  - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin(). |    - Mouse wheel:                   Scroll vertically. | ||||||
|  - Click and drag on lower right corner to resize window (double-click to auto fit window to its contents). |    - SHIFT+Mouse wheel:             Scroll horizontally. | ||||||
|  - Click and drag on any empty space to move window. |    - Click [X]:                     Close a window, available when 'bool* p_open' is passed to ImGui::Begin(). | ||||||
|  - TAB/SHIFT+TAB to cycle through keyboard editable fields. |    - Click ^, Double-Click title:   Collapse window. | ||||||
|  - CTRL+Click on a slider or drag box to input value as text. |    - Drag on corner/border:         Resize window (double-click to auto fit window to its contents). | ||||||
|  - Use mouse wheel to scroll. |    - Drag on any empty space:       Move window (unless io.ConfigWindowsMoveFromTitleBarOnly = true). | ||||||
|  - Text editor: |    - Left-click outside popup:      Close popup stack (right-click over underlying popup: Partially close popup stack). | ||||||
|    - Hold SHIFT or use mouse to select text. |  | ||||||
|    - CTRL+Left/Right to word jump. |  - TEXT EDITOR | ||||||
|    - CTRL+Shift+Left/Right to select words. |    - Hold SHIFT or Drag Mouse:      Select text. | ||||||
|    - CTRL+A or Double-Click to select all. |    - CTRL+Left/Right:               Word jump. | ||||||
|    - CTRL+X,CTRL+C,CTRL+V to use OS clipboard/ |    - CTRL+Shift+Left/Right:         Select words. | ||||||
|    - CTRL+Z,CTRL+Y to undo/redo. |    - CTRL+A or Double-Click:        Select All. | ||||||
|    - ESCAPE to revert text to its original value. |    - CTRL+X, CTRL+C, CTRL+V:        Use OS clipboard. | ||||||
|    - Controls are automatically adjusted for OSX to match standard OSX text editing operations. |    - CTRL+Z, CTRL+Y:                Undo, Redo. | ||||||
|  - General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard. |    - ESCAPE:                        Revert text to its original value. | ||||||
|  - General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. Download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets |    - On OSX, controls are automatically adjusted to match standard OSX text editing shortcuts and behaviors. | ||||||
|  |  | ||||||
|  |  - KEYBOARD CONTROLS | ||||||
|  |    - Basic: | ||||||
|  |      - Tab, SHIFT+Tab               Cycle through text editable fields. | ||||||
|  |      - CTRL+Tab, CTRL+Shift+Tab     Cycle through windows. | ||||||
|  |      - CTRL+Click                   Input text into a Slider or Drag widget. | ||||||
|  |    - Extended features with `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard`: | ||||||
|  |      - Tab, SHIFT+Tab:              Cycle through every items. | ||||||
|  |      - Arrow keys                   Move through items using directional navigation. Tweak value. | ||||||
|  |      - Arrow keys + Alt, Shift      Tweak slower, tweak faster (when using arrow keys). | ||||||
|  |      - Enter                        Activate item (prefer text input when possible). | ||||||
|  |      - Space                        Activate item (prefer tweaking with arrows when possible). | ||||||
|  |      - Escape                       Deactivate item, leave child window, close popup. | ||||||
|  |      - Page Up, Page Down           Previous page, next page. | ||||||
|  |      - Home, End                    Scroll to top, scroll to bottom. | ||||||
|  |      - Alt                          Toggle between scrolling layer and menu layer. | ||||||
|  |      - CTRL+Tab then Ctrl+Arrows    Move window. Hold SHIFT to resize instead of moving. | ||||||
|  |    - Output when ImGuiConfigFlags_NavEnableKeyboard set, | ||||||
|  |      - io.WantCaptureKeyboard flag is set when keyboard is claimed. | ||||||
|  |      - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. | ||||||
|  |      - io.NavVisible: true when the navigation cursor is visible (usually goes to back false when mouse is used). | ||||||
|  |  | ||||||
|  |  - GAMEPAD CONTROLS | ||||||
|  |    - Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. | ||||||
|  |    - Particularly useful to use Dear ImGui on a console system (e.g. PlayStation, Switch, Xbox) without a mouse! | ||||||
|  |    - Download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets | ||||||
|  |    - Backend support: backend needs to: | ||||||
|  |       - Set 'io.BackendFlags |= ImGuiBackendFlags_HasGamepad' + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys. | ||||||
|  |       - For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly. | ||||||
|  |         Backend code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). | ||||||
|  |       - BEFORE 1.87, BACKENDS USED TO WRITE TO io.NavInputs[]. This is now obsolete. Please call io functions instead! | ||||||
|  |    - If you need to share inputs between your game and the Dear ImGui interface, the easiest approach is to go all-or-nothing, | ||||||
|  |      with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. | ||||||
|  |  | ||||||
|  |  - REMOTE INPUTS SHARING & MOUSE EMULATION | ||||||
|  |    - PS4/PS5 users: Consider emulating a mouse cursor with DualShock touch pad or a spare analog stick as a mouse-emulation fallback. | ||||||
|  |    - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + run examples/libs/synergy/uSynergy.c (on your console/tablet/phone app) | ||||||
|  |      in order to share your PC mouse/keyboard. | ||||||
|  |    - See https://github.com/ocornut/imgui/wiki/Useful-Extensions#remoting for other remoting solutions. | ||||||
|  |    - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. | ||||||
|  |      Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs Dear ImGui to move your mouse cursor along with navigation movements. | ||||||
|  |      When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. | ||||||
|  |      When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. | ||||||
|  |      (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, Dear ImGui will misbehave as it will see your mouse moving back & forth!) | ||||||
|  |      (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want | ||||||
|  |      to set a boolean to ignore your other external mouse positions until the external source is moved again.) | ||||||
|  |  | ||||||
|  |  | ||||||
|  PROGRAMMER GUIDE |  PROGRAMMER GUIDE | ||||||
| @@ -344,41 +389,6 @@ CODE | |||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  USING KEYBOARD/GAMEPAD NAVIGATION CONTROLS |  | ||||||
|  ------------------------------------------ |  | ||||||
|  - The keyboard/gamepad navigation is fairly functional and keeps being improved. |  | ||||||
|  - Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PlayStation, Switch, Xbox) without a mouse! |  | ||||||
|  - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. |  | ||||||
|  - Keyboard: |  | ||||||
|     - Application: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. |  | ||||||
|     - Arrow keys to move. Space or Enter to activate (on a slider/drag: Space will tweak with arrow, Enter will input text). |  | ||||||
|     - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), |  | ||||||
|       the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from: |  | ||||||
|        - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. |  | ||||||
|        - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). |  | ||||||
|        - or query focus information with e.g. IsWindowFocused(ImGuiFocusedFlags_AnyWindow), IsItemFocused() etc. functions. |  | ||||||
|       Please reach out if you think the game vs navigation input sharing could be improved. |  | ||||||
|  - Gamepad: |  | ||||||
|     - Application: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. |  | ||||||
|     - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys. |  | ||||||
|       For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly. |  | ||||||
|       Backend code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). |  | ||||||
|     - BEFORE 1.87, BACKENDS USED TO WRITE TO io.NavInputs[]. This is now obsolete. Please call io functions instead! |  | ||||||
|     - You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://dearimgui.org/controls_sheets |  | ||||||
|     - If you need to share inputs between your game and the Dear ImGui interface, the easiest approach is to go all-or-nothing, |  | ||||||
|       with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. |  | ||||||
|  - Mouse: |  | ||||||
|     - PS4/PS5 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. |  | ||||||
|     - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (on your console/tablet/phone app) to share your PC mouse/keyboard. |  | ||||||
|     - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. |  | ||||||
|       Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs dear imgui to move your mouse cursor along with navigation movements. |  | ||||||
|       When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. |  | ||||||
|       When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. |  | ||||||
|       (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, imgui will misbehave as it will see your mouse moving back and forth!) |  | ||||||
|       (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want |  | ||||||
|        to set a boolean to ignore your other external mouse positions until the external source is moved again.) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  API BREAKING CHANGES |  API BREAKING CHANGES | ||||||
|  ==================== |  ==================== | ||||||
|  |  | ||||||
| @@ -1013,7 +1023,7 @@ static void             NavEndFrame(); | |||||||
| static bool             NavScoreItem(ImGuiNavItemData* result); | static bool             NavScoreItem(ImGuiNavItemData* result); | ||||||
| static void             NavApplyItemToResult(ImGuiNavItemData* result); | static void             NavApplyItemToResult(ImGuiNavItemData* result); | ||||||
| static void             NavProcessItem(); | static void             NavProcessItem(); | ||||||
| static void             NavProcessItemForTabbingRequest(ImGuiID id); | static void             NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags); | ||||||
| static ImVec2           NavCalcPreferredRefPos(); | static ImVec2           NavCalcPreferredRefPos(); | ||||||
| static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | ||||||
| static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | ||||||
| @@ -10746,16 +10756,14 @@ static void ImGui::NavProcessItem() | |||||||
|  |  | ||||||
|     // Process Move Request (scoring for navigation) |     // Process Move Request (scoring for navigation) | ||||||
|     // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) |     // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) | ||||||
|     if (g.NavMoveScoringItems) |     if (g.NavMoveScoringItems && (item_flags & ImGuiItemFlags_Disabled) == 0) | ||||||
|     { |     { | ||||||
|         const bool is_tab_stop = (item_flags & ImGuiItemFlags_Inputable) && (item_flags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; |  | ||||||
|         const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; |         const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; | ||||||
|         if (is_tabbing) |         if (is_tabbing) | ||||||
|         { |         { | ||||||
|             if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi)) |             NavProcessItemForTabbingRequest(id, item_flags, g.NavMoveFlags); | ||||||
|                 NavProcessItemForTabbingRequest(id); |  | ||||||
|         } |         } | ||||||
|         else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & ImGuiItemFlags_Disabled)) |         else if (g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) | ||||||
|         { |         { | ||||||
|             ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; |             ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; | ||||||
|             if (NavScoreItem(result)) |             if (NavScoreItem(result)) | ||||||
| @@ -10789,18 +10797,31 @@ static void ImGui::NavProcessItem() | |||||||
| // - Case 3: tab forward wrap:    set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request | // - Case 3: tab forward wrap:    set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request | ||||||
| // - Case 4: tab backward:        store all results, on ref id pick prev, stop storing | // - Case 4: tab backward:        store all results, on ref id pick prev, stop storing | ||||||
| // - Case 5: tab backward wrap:   store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested | // - Case 5: tab backward wrap:   store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested | ||||||
| void ImGui::NavProcessItemForTabbingRequest(ImGuiID id) | void ImGui::NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |  | ||||||
|  |     if ((move_flags & ImGuiNavMoveFlags_FocusApi) == 0) | ||||||
|  |         if (g.NavLayer != g.CurrentWindow->DC.NavLayerCurrent) | ||||||
|  |             return; | ||||||
|  |  | ||||||
|  |     // - Can always land on an item when using API call. | ||||||
|  |     // - Tabbing with _NavEnableKeyboard (space/enter/arrows): goes through every item. | ||||||
|  |     // - Tabbing without _NavEnableKeyboard: goes through inputable items only. | ||||||
|  |     bool can_stop; | ||||||
|  |     if (move_flags & ImGuiNavMoveFlags_FocusApi) | ||||||
|  |         can_stop = true; | ||||||
|  |     else | ||||||
|  |         can_stop = (item_flags & ImGuiItemFlags_NoTabStop) == 0 && ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) || (item_flags & ImGuiItemFlags_Inputable)); | ||||||
|  |  | ||||||
|     // Always store in NavMoveResultLocal (unlike directional request which uses NavMoveResultOther on sibling/flattened windows) |     // Always store in NavMoveResultLocal (unlike directional request which uses NavMoveResultOther on sibling/flattened windows) | ||||||
|     ImGuiNavItemData* result = &g.NavMoveResultLocal; |     ImGuiNavItemData* result = &g.NavMoveResultLocal; | ||||||
|     if (g.NavTabbingDir == +1) |     if (g.NavTabbingDir == +1) | ||||||
|     { |     { | ||||||
|         // Tab Forward or SetKeyboardFocusHere() with >= 0 |         // Tab Forward or SetKeyboardFocusHere() with >= 0 | ||||||
|         if (g.NavTabbingResultFirst.ID == 0) |         if (can_stop && g.NavTabbingResultFirst.ID == 0) | ||||||
|             NavApplyItemToResult(&g.NavTabbingResultFirst); |             NavApplyItemToResult(&g.NavTabbingResultFirst); | ||||||
|         if (--g.NavTabbingCounter == 0) |         if (can_stop && g.NavTabbingCounter > 0 && --g.NavTabbingCounter == 0) | ||||||
|             NavMoveRequestResolveWithLastItem(result); |             NavMoveRequestResolveWithLastItem(result); | ||||||
|         else if (g.NavId == id) |         else if (g.NavId == id) | ||||||
|             g.NavTabbingCounter = 1; |             g.NavTabbingCounter = 1; | ||||||
| @@ -10816,16 +10837,18 @@ void ImGui::NavProcessItemForTabbingRequest(ImGuiID id) | |||||||
|                 NavUpdateAnyRequestFlag(); |                 NavUpdateAnyRequestFlag(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else |         else if (can_stop) | ||||||
|         { |         { | ||||||
|  |             // Keep applying until reaching NavId | ||||||
|             NavApplyItemToResult(result); |             NavApplyItemToResult(result); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else if (g.NavTabbingDir == 0) |     else if (g.NavTabbingDir == 0) | ||||||
|     { |     { | ||||||
|         // Tab Init |         if (can_stop && g.NavId == id) | ||||||
|         if (g.NavTabbingResultFirst.ID == 0) |             NavMoveRequestResolveWithLastItem(result); | ||||||
|             NavMoveRequestResolveWithLastItem(&g.NavTabbingResultFirst); |         if (can_stop && g.NavTabbingResultFirst.ID == 0) // Tab init | ||||||
|  |             NavApplyItemToResult(&g.NavTabbingResultFirst); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -11348,8 +11371,11 @@ void ImGui::NavUpdateCreateTabbingRequest() | |||||||
|     // (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!) |     // (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!) | ||||||
|     // Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests. |     // Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests. | ||||||
|     // See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping. |     // See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping. | ||||||
|     //// FIXME: We use (g.ActiveId == 0) but (g.NavDisableHighlight == false) might be righter once we can tab through anything |     const bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; | ||||||
|     g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; |     if (nav_keyboard_active) | ||||||
|  |         g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1; | ||||||
|  |     else | ||||||
|  |         g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; | ||||||
|     ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; |     ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; | ||||||
|     ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; |     ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; | ||||||
|     NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. |     NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. | ||||||
| @@ -11369,7 +11395,7 @@ void ImGui::NavMoveRequestApplyResult() | |||||||
|     ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; |     ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; | ||||||
|  |  | ||||||
|     // Tabbing forward wrap |     // Tabbing forward wrap | ||||||
|     if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) |     if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && result == NULL) | ||||||
|         if ((g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) && g.NavTabbingResultFirst.ID) |         if ((g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) && g.NavTabbingResultFirst.ID) | ||||||
|             result = &g.NavTabbingResultFirst; |             result = &g.NavTabbingResultFirst; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1495,7 +1495,7 @@ enum ImGuiNavInput | |||||||
| enum ImGuiConfigFlags_ | enum ImGuiConfigFlags_ | ||||||
| { | { | ||||||
|     ImGuiConfigFlags_None                   = 0, |     ImGuiConfigFlags_None                   = 0, | ||||||
|     ImGuiConfigFlags_NavEnableKeyboard      = 1 << 0,   // Master keyboard navigation enable flag. |     ImGuiConfigFlags_NavEnableKeyboard      = 1 << 0,   // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate. | ||||||
|     ImGuiConfigFlags_NavEnableGamepad       = 1 << 1,   // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. |     ImGuiConfigFlags_NavEnableGamepad       = 1 << 1,   // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. | ||||||
|     ImGuiConfigFlags_NavEnableSetMousePos   = 1 << 2,   // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. |     ImGuiConfigFlags_NavEnableSetMousePos   = 1 << 2,   // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. | ||||||
|     ImGuiConfigFlags_NavNoCaptureKeyboard   = 1 << 3,   // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. |     ImGuiConfigFlags_NavNoCaptureKeyboard   = 1 << 3,   // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut