Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
This commit is contained in:
ocornut 2021-10-11 19:25:50 +02:00
commit 1b215ecb01
12 changed files with 192 additions and 106 deletions

View File

@ -121,9 +121,11 @@ void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data)
struct BackupSDLRendererState struct BackupSDLRendererState
{ {
SDL_Rect Viewport; SDL_Rect Viewport;
bool ClipEnabled;
SDL_Rect ClipRect; SDL_Rect ClipRect;
}; };
BackupSDLRendererState old = {}; BackupSDLRendererState old = {};
old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer);
SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport); SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport);
SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect); SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect);
@ -184,7 +186,7 @@ void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data)
// Restore modified SDL_Renderer state // Restore modified SDL_Renderer state
SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport); SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport);
SDL_RenderSetClipRect(bd->SDLRenderer, &old.ClipRect); SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : NULL);
} }
// Called by Init/NewFrame/Shutdown // Called by Init/NewFrame/Shutdown

View File

@ -270,7 +270,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_
spirv_desc.codeSize = binary_data_size; spirv_desc.codeSize = binary_data_size;
spirv_desc.code = binary_data; spirv_desc.code = binary_data;
WGPUShaderModuleDescriptor desc; WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc); desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc);
WGPUProgrammableStageDescriptor stage_desc = {}; WGPUProgrammableStageDescriptor stage_desc = {};

View File

@ -100,14 +100,20 @@ Other changes:
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.85 WIP (In Progress) VERSION 1.85 (Released 2021-10-12)
----------------------------------------------------------------------- -----------------------------------------------------------------------
This is the last release officially supporting C++03 and Visual Studio 2008/2010. (#4537)
We expect that the next release will require a subset of the C++11 language (VS 2012~, GCC 4.8.1, Clang 3.3).
We may use some C++11 language features but we will not use any C++ library headers.
If you are stuck on ancient compiler you may need to stay at this version onward.
Breaking Changes: Breaking Changes:
- Removed GetWindowContentRegionWidth() function. keep inline redirection helper. - Removed GetWindowContentRegionWidth() function. keep inline redirection helper.
Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not
very useful in practice, and the only use of it in the demo was illfit. very useful in practice, and the only use of it in the demo was illfit.
Using 'GetContentRegionAvail().x' is generally a better choice.
- (Docking branch) IsWindowFocused() and IsWindowHovered() with only the _ChildWindows flag - (Docking branch) IsWindowFocused() and IsWindowHovered() with only the _ChildWindows flag
and without the _RootWindow flag used to leak docking hierarchy, so a docked window would and without the _RootWindow flag used to leak docking hierarchy, so a docked window would
return as the child of the window hosting the dockspace. This was inconsistent and incorrect return as the child of the window hosting the dockspace. This was inconsistent and incorrect
@ -115,7 +121,7 @@ Breaking Changes:
Other Changes: Other Changes:
- Debug: Stack Tool: Added "Stack Tool" available in "Demo->Examples->Stack Tool", "Metrics->Tools", - Debug: Stack Tool: Added "Stack Tool" available in "Demo->Tools->Stack Tool", "Metrics->Tools",
or by calling the ShowStackToolWindow() function. The tool run queries on hovered id to display or by calling the ShowStackToolWindow() function. The tool run queries on hovered id to display
details about individual components that were hashed to create an ID. It helps understanding details about individual components that were hashed to create an ID. It helps understanding
the ID stack system and debugging potential ID collisions. (#4631) [@ocornut, @rokups] the ID stack system and debugging potential ID collisions. (#4631) [@ocornut, @rokups]
@ -127,11 +133,19 @@ Other Changes:
- InputTextMultiline: Fixed label size not being included into window contents rect unless - InputTextMultiline: Fixed label size not being included into window contents rect unless
the whole widget is clipped. the whole widget is clipped.
- InputText: Allow activating/cancelling/validating input with gamepad nav events. (#2321, #4552) - InputText: Allow activating/cancelling/validating input with gamepad nav events. (#2321, #4552)
- InputText: Fixed selection rectangle appearing one frame late when selecting all.
- TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform - TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform
to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615) to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615)
- Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211) - Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211)
- Nav: Fixed using SetKeyboardFocusHere() on non-visible/clipped items. It now works and will scroll
toward the item. When called during a frame where the parent window is appearing, scrolling will
aim to center the item in the window. When calling during a frame where the parent window is already
visible, scrolling will aim to scroll as little as possible to make the item visible. We will later
expose scroll functions and flags in public API to select those behaviors. (#343, #4079, #2352)
- Nav: Fixed using SetKeyboardFocusHere() from activating a different item on the next frame if
submitted items have changed during that frame. (#432)
- Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when - Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when
the NavEnableSetMousePos config flag is set. the ImGuiConfigFlags_NavEnableSetMousePos config flag is set.
- Nav: Fixed a few widgets from not setting reference keyboard/gamepad navigation ID when - Nav: Fixed a few widgets from not setting reference keyboard/gamepad navigation ID when
activated with mouse. More specifically: BeginTabItem(), the scrolling arrows of BeginTabBar(), activated with mouse. More specifically: BeginTabItem(), the scrolling arrows of BeginTabBar(),
the arrow section of TreeNode(), the +/- buttons of InputInt()/InputFloat(), Selectable() with the arrow section of TreeNode(), the +/- buttons of InputInt()/InputFloat(), Selectable() with
@ -139,11 +153,12 @@ Other Changes:
the PressedOnClick/PressedOnDoubleClick/PressedOnRelease button policy. the PressedOnClick/PressedOnDoubleClick/PressedOnRelease button policy.
- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation - Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation
is disabled. (#4547, #4439) [@PathogenDavid] is disabled. (#4547, #4439) [@PathogenDavid]
- Nav: Fixed vertical scoring offset when wrapping on Y in a decorated window.
- Nav: Improve scrolling behavior when navigating to an item larger than view. - Nav: Improve scrolling behavior when navigating to an item larger than view.
- TreePush(): removed unnecessary/inconsistent legacy behavior where passing a NULL value to - TreePush(): removed unnecessary/inconsistent legacy behavior where passing a NULL value to
the TreePush(const char*) and TreePush(const void*) functions would use an hardcoded replacement. the TreePush(const char*) and TreePush(const void*) functions would use an hard-coded replacement.
The only situation where that change would make a meaningful difference is TreePush((const char*)NULL) The only situation where that change would make a meaningful difference is TreePush((const char*)NULL)
(_explicitely_ casting a null pointer to const char*), which is unlikely and will now crash. (_explicitly_ casting a null pointer to const char*), which is unlikely and will now crash.
You may replace it with anything else. You may replace it with anything else.
- ColorEdit4: Fixed not being able to change hue when saturation is 0. (#4014) [@rokups] - ColorEdit4: Fixed not being able to change hue when saturation is 0. (#4014) [@rokups]
- ColorEdit4: Fixed hue resetting to 0 when it is set to 255. [@rokups] - ColorEdit4: Fixed hue resetting to 0 when it is set to 255. [@rokups]
@ -151,9 +166,11 @@ Other Changes:
RGB<>HSV round trips every frames. [@rokups] RGB<>HSV round trips every frames. [@rokups]
- ColorPicker4: Fixed picker being unable to select exact 1.0f color when dragging toward the edges - ColorPicker4: Fixed picker being unable to select exact 1.0f color when dragging toward the edges
of the SV square (previously picked 0.999989986f). (#3517) [@rokups] of the SV square (previously picked 0.999989986f). (#3517) [@rokups]
- Menus: Fixed vertical alignments of MenuItem() calls within a menu bar. (broken in 1.84). (#4538) - Menus: Fixed vertical alignments of MenuItem() calls within a menu bar (broken in 1.84). (#4538)
- Menus: Adjust closing logic to accomodate for varying font size and dpi. - Menus: Improve closing logic when moving diagonally in empty between between parent and child menus to
accommodate for varying font size and dpi.
- Menus: Fixed crash when navigating left inside a child window inside a sub-menu. (#4510). - Menus: Fixed crash when navigating left inside a child window inside a sub-menu. (#4510).
- Menus: Fixed an assertion happening in some situations when closing nested menus (broken in 1.83). (#4640)
- Drag and Drop: Fixed using BeginDragDropSource() inside a BeginChild() that returned false. (#4515) - Drag and Drop: Fixed using BeginDragDropSource() inside a BeginChild() that returned false. (#4515)
- PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini] - PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini]
- Misc: Added asserts for missing PopItemFlag() calls. - Misc: Added asserts for missing PopItemFlag() calls.
@ -185,7 +202,7 @@ Docking+Viewports Branch:
- Docking: Fixed IsItemHovered() and functions depending on it (e.g. BeginPopupContextItem()) when - Docking: Fixed IsItemHovered() and functions depending on it (e.g. BeginPopupContextItem()) when
called after Begin() on a docked window (broken 2021/03/04). (#3851) called after Begin() on a docked window (broken 2021/03/04). (#3851)
- Docking: Improved resizing system so that non-central zone are better at keeping their fixed size. - Docking: Improved resizing system so that non-central zone are better at keeping their fixed size.
The algorithm is still not handling the repartition of size idealy for nested sibling, but it got better. The algorithm is still not handling the allocation of size ideally for nested sibling, but it got better.
- Docking: Fixed settings load issue when mouse wheeling. (#4310) - Docking: Fixed settings load issue when mouse wheeling. (#4310)
- Docking: Fixed manually created floating node with a central node from not hiding when windows are gone. - Docking: Fixed manually created floating node with a central node from not hiding when windows are gone.
- Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin() - Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin()

View File

@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | | [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | | [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** | | **Q&A: Usage** |
| **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** | | **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-about-the-id-stack-system)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| | [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
| [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) | | [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) |
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) | | [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
@ -186,17 +186,23 @@ Refer to rendering backends in the [examples/](https://github.com/ocornut/imgui/
# Q&A: Usage # Q&A: Usage
### Q: About the ID Stack system...
### Q: Why is my widget not reacting when I click on it? ### Q: Why is my widget not reacting when I click on it?
### Q: How can I have widgets with an empty label? ### Q: How can I have widgets with an empty label?
### Q: How can I have multiple widgets with the same label? ### Q: How can I have multiple widgets with the same label?
A primer on labels and the ID Stack... A primer on labels and the ID Stack...
Dear ImGui internally need to uniquely identify UI elements. Dear ImGui internally needs to uniquely identify UI elements.
Elements that are typically not clickable (such as calls to the Text functions) don't need an ID. Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
Interactive widgets (such as calls to Button buttons) need a unique ID. Interactive widgets (such as calls to Button buttons) need a unique ID.
Unique ID are used internally to track active widgets and occasionally associate state to widgets.
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element. **Unique ID are used internally to track active widgets and occasionally associate state to widgets.<BR>
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.**
Since Dear ImGui 1.85 you can use `Demo>Tools>Stack Tool` or call `ImGui::ShowStackToolWindow()`. The tool display intermediate values leading to the creation of a unique ID, making things easier to debug and understand.
![Stack tool](https://user-images.githubusercontent.com/8225057/136235657-a0ea5665-dcd1-423f-9be6-dc3f8ced8f12.png)
- Unique ID are often derived from a string label and at minimum scoped within their host window: - Unique ID are often derived from a string label and at minimum scoped within their host window:
```cpp ```cpp

View File

@ -354,6 +354,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?) - nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?)
- nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ? - nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ?
! nav: never clear NavId on some setup (e.g. gamepad centric) ! nav: never clear NavId on some setup (e.g. gamepad centric)
- nav: scroll up/down if possible when move request fails
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable. - nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
- nav: code to focus child-window on restoring NavId appears to have issue: e.g. when focus change is implicit because of window closure. - nav: code to focus child-window on restoring NavId appears to have issue: e.g. when focus change is implicit because of window closure.
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view? - nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
@ -381,8 +382,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav/windowing: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering. - nav/windowing: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied - nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
- focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787, #343)
- viewport: make it possible to have no main/hosting viewport - viewport: make it possible to have no main/hosting viewport
- viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without - viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without

119
imgui.cpp
View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -390,7 +390,7 @@ CODE
- 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. - 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead. - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead for generally 'GetContentRegionAvail().x' is more useful.
- 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder - ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
@ -3366,7 +3366,6 @@ void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id)
// Increment counters // Increment counters
// FIXME: ImGuiItemFlags_Disabled should disable more. // FIXME: ImGuiItemFlags_Disabled should disable more.
const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
window->DC.FocusCounterRegular++;
if (is_tab_stop) if (is_tab_stop)
{ {
window->DC.FocusCounterTabStop++; window->DC.FocusCounterTabStop++;
@ -3385,11 +3384,6 @@ void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id)
// Handle focus requests // Handle focus requests
if (g.TabFocusRequestCurrWindow == window) if (g.TabFocusRequestCurrWindow == window)
{ {
if (window->DC.FocusCounterRegular == g.TabFocusRequestCurrCounterRegular)
{
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByCode;
return;
}
if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop) if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop)
{ {
g.NavJustTabbedId = id; // FIXME-NAV: aim to eventually set in NavUpdate() once we finish the refactor g.NavJustTabbedId = id; // FIXME-NAV: aim to eventually set in NavUpdate() once we finish the refactor
@ -3977,7 +3971,10 @@ void ImGui::UpdateTabFocus()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
// Pressing TAB activate widget focus // Pressing TAB activate widget focus
g.TabFocusPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && !IsActiveIdUsingKey(ImGuiKey_Tab)); g.TabFocusPressed = false;
if (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
if (!g.IO.KeyCtrl && !g.IO.KeyAlt && IsKeyPressedMap(ImGuiKey_Tab) && !IsActiveIdUsingKey(ImGuiKey_Tab))
g.TabFocusPressed = true;
if (g.ActiveId == 0 && g.TabFocusPressed) if (g.ActiveId == 0 && g.TabFocusPressed)
{ {
// - This path is only taken when no widget are active/tabbed-into yet. // - This path is only taken when no widget are active/tabbed-into yet.
@ -3985,7 +3982,6 @@ void ImGui::UpdateTabFocus()
// - Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also // - Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
// manipulate the Next fields here even though they will be turned into Curr fields below. // manipulate the Next fields here even though they will be turned into Curr fields below.
g.TabFocusRequestNextWindow = g.NavWindow; g.TabFocusRequestNextWindow = g.NavWindow;
g.TabFocusRequestNextCounterRegular = INT_MAX;
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + (g.IO.KeyShift ? -1 : 0); g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + (g.IO.KeyShift ? -1 : 0);
else else
@ -3994,17 +3990,15 @@ void ImGui::UpdateTabFocus()
// Turn queued focus request into current one // Turn queued focus request into current one
g.TabFocusRequestCurrWindow = NULL; g.TabFocusRequestCurrWindow = NULL;
g.TabFocusRequestCurrCounterRegular = g.TabFocusRequestCurrCounterTabStop = INT_MAX; g.TabFocusRequestCurrCounterTabStop = INT_MAX;
if (g.TabFocusRequestNextWindow != NULL) if (g.TabFocusRequestNextWindow != NULL)
{ {
ImGuiWindow* window = g.TabFocusRequestNextWindow; ImGuiWindow* window = g.TabFocusRequestNextWindow;
g.TabFocusRequestCurrWindow = window; g.TabFocusRequestCurrWindow = window;
if (g.TabFocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
g.TabFocusRequestCurrCounterRegular = ImModPositive(g.TabFocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1) if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1); g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
g.TabFocusRequestNextWindow = NULL; g.TabFocusRequestNextWindow = NULL;
g.TabFocusRequestNextCounterRegular = g.TabFocusRequestNextCounterTabStop = INT_MAX; g.TabFocusRequestNextCounterTabStop = INT_MAX;
} }
g.NavIdTabCounter = INT_MAX; g.NavIdTabCounter = INT_MAX;
@ -6790,7 +6784,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.CurrentColumns = NULL; window->DC.CurrentColumns = NULL;
window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical;
window->DC.FocusCounterRegular = window->DC.FocusCounterTabStop = -1; window->DC.FocusCounterTabStop = -1;
window->DC.ItemWidth = window->ItemWidthDefault; window->DC.ItemWidth = window->ItemWidthDefault;
window->DC.TextWrapPos = -1.0f; // disabled window->DC.TextWrapPos = -1.0f; // disabled
@ -7094,8 +7088,18 @@ void ImGui::FocusWindow(ImGuiWindow* window)
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window) void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
int start_idx = g.WindowsFocusOrder.Size - 1;
const int start_idx = ((under_this_window != NULL) ? FindWindowFocusIndex(under_this_window) : g.WindowsFocusOrder.Size) - 1; if (under_this_window != NULL)
{
// Aim at root window behind us, if we are in a child window that's our own root (see #4640)
int offset = -1;
while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow)
{
under_this_window = under_this_window->ParentWindow;
offset = 0;
}
start_idx = FindWindowFocusIndex(under_this_window) + offset;
}
for (int i = start_idx; i >= 0; i--) for (int i = start_idx; i >= 0; i--)
{ {
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
@ -7677,12 +7681,16 @@ void ImGui::PopFocusScope()
void ImGui::SetKeyboardFocusHere(int offset) void ImGui::SetKeyboardFocusHere(int offset)
{ {
IM_ASSERT(offset >= -1); // -1 is allowed but not below
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
g.TabFocusRequestNextWindow = window; IM_ASSERT(offset >= -1); // -1 is allowed but not below
g.TabFocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset; g.NavWindow = window;
g.TabFocusRequestNextCounterTabStop = INT_MAX; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_None, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
if (offset == -1)
NavMoveRequestResolveWithLastItem();
else
g.NavTabbingInputableRemaining = offset + 1;
} }
void ImGui::SetItemDefaultFocus() void ImGui::SetItemDefaultFocus()
@ -7691,15 +7699,17 @@ void ImGui::SetItemDefaultFocus()
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
if (!window->Appearing) if (!window->Appearing)
return; return;
if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == window->DC.NavLayerCurrent) if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResultId == 0) || g.NavLayer != window->DC.NavLayerCurrent)
{ return;
g.NavInitRequest = false; g.NavInitRequest = false;
g.NavInitResultId = g.LastItemData.ID; g.NavInitResultId = g.LastItemData.ID;
g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos); g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
NavUpdateAnyRequestFlag(); NavUpdateAnyRequestFlag();
// Scroll could be done in NavInitRequestApplyResult() via a opt-in flag (we however don't want regular init requests to scroll)
if (!IsItemVisible()) if (!IsItemVisible())
SetScrollHereY(); ScrollToRectEx(window, g.LastItemData.Rect, ImGuiScrollFlags_None);
}
} }
void ImGui::SetStateStorage(ImGuiStorage* tree) void ImGui::SetStateStorage(ImGuiStorage* tree)
@ -9625,6 +9635,7 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
result->Window = window; result->Window = window;
result->ID = g.LastItemData.ID; result->ID = g.LastItemData.ID;
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent; result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
result->InFlags = g.LastItemData.InFlags;
result->RectRel = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos); result->RectRel = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos);
} }
@ -9659,9 +9670,20 @@ static void ImGui::NavProcessItem()
// 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)
{ {
if (item_flags & ImGuiItemFlags_Inputable)
g.NavTabbingInputableRemaining--;
if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav)))
{ {
ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
{
if (g.NavTabbingInputableRemaining == 0)
NavMoveRequestResolveWithLastItem();
}
else
{
if (NavScoreItem(result)) if (NavScoreItem(result))
NavApplyItemToResult(result); NavApplyItemToResult(result);
@ -9673,6 +9695,7 @@ static void ImGui::NavProcessItem()
NavApplyItemToResult(&g.NavMoveResultLocalVisible); NavApplyItemToResult(&g.NavMoveResultLocalVisible);
} }
} }
}
// Update window-relative bounding box of navigated item // Update window-relative bounding box of navigated item
if (g.NavId == id) if (g.NavId == id)
@ -9696,6 +9719,10 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.NavWindow != NULL); IM_ASSERT(g.NavWindow != NULL);
if (move_flags & ImGuiNavMoveFlags_Tabbing)
move_flags |= ImGuiNavMoveFlags_AllowCurrentNavId;
g.NavMoveSubmitted = g.NavMoveScoringItems = true; g.NavMoveSubmitted = g.NavMoveScoringItems = true;
g.NavMoveDir = move_dir; g.NavMoveDir = move_dir;
g.NavMoveDirForDebug = move_dir; g.NavMoveDirForDebug = move_dir;
@ -9704,12 +9731,21 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
g.NavMoveScrollFlags = scroll_flags; g.NavMoveScrollFlags = scroll_flags;
g.NavMoveForwardToNextFrame = false; g.NavMoveForwardToNextFrame = false;
g.NavMoveKeyMods = g.IO.KeyMods; g.NavMoveKeyMods = g.IO.KeyMods;
g.NavTabbingInputableRemaining = 0;
g.NavMoveResultLocal.Clear(); g.NavMoveResultLocal.Clear();
g.NavMoveResultLocalVisible.Clear(); g.NavMoveResultLocalVisible.Clear();
g.NavMoveResultOther.Clear(); g.NavMoveResultOther.Clear();
NavUpdateAnyRequestFlag(); NavUpdateAnyRequestFlag();
} }
void ImGui::NavMoveRequestResolveWithLastItem()
{
ImGuiContext& g = *GImGui;
g.NavMoveScoringItems = false; // Ensure request doesn't need more processing
NavApplyItemToResult(&g.NavMoveResultLocal);
NavUpdateAnyRequestFlag();
}
void ImGui::NavMoveRequestCancel() void ImGui::NavMoveRequestCancel()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -9933,6 +9969,7 @@ static void ImGui::NavUpdate()
// Process navigation move request // Process navigation move request
if (g.NavMoveSubmitted) if (g.NavMoveSubmitted)
NavMoveRequestApplyResult(); NavMoveRequestApplyResult();
g.NavTabbingInputableRemaining = 0;
g.NavMoveSubmitted = g.NavMoveScoringItems = false; g.NavMoveSubmitted = g.NavMoveScoringItems = false;
// Apply application mouse position movement, after we had a chance to process move request result. // Apply application mouse position movement, after we had a chance to process move request result.
@ -9950,7 +9987,7 @@ static void ImGui::NavUpdate()
} }
g.NavIdIsAlive = false; g.NavIdIsAlive = false;
g.NavJustTabbedId = 0; g.NavJustTabbedId = 0;
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1); IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu);
// Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0 // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0
if (g.NavWindow) if (g.NavWindow)
@ -10184,7 +10221,9 @@ void ImGui::NavMoveRequestApplyResult()
// In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
if (result == NULL) if (result == NULL)
{ {
if (g.NavId != 0) if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
{ {
g.NavDisableHighlight = false; g.NavDisableHighlight = false;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
@ -10239,10 +10278,28 @@ void ImGui::NavMoveRequestApplyResult()
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name); IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel); SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
// Tabbing: Activates Inputable or Focus non-Inputable
if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable))
{
g.NavNextActivateId = result->ID;
g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
}
// Activate
if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate)
{
g.NavNextActivateId = result->ID;
g.NavNextActivateFlags = ImGuiActivateFlags_None;
}
// Enable nav highlight // Enable nav highlight
if ((g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
{
g.NavDisableHighlight = false; g.NavDisableHighlight = false;
g.NavDisableMouseHover = g.NavMousePosDirty = true; g.NavDisableMouseHover = g.NavMousePosDirty = true;
} }
}
// Process NavCancel input (to close a popup, get back to parent, clear focus) // Process NavCancel input (to close a popup, get back to parent, clear focus)
// FIXME: In order to support e.g. Escape to clear a selection we'll need: // FIXME: In order to support e.g. Escape to clear a selection we'll need:
@ -10406,10 +10463,11 @@ static void ImGui::NavEndFrame()
} }
do_forward = true; do_forward = true;
} }
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
{ {
bb_rel.Min.y = bb_rel.Max.y = bb_rel.Min.y = bb_rel.Max.y =
ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y; ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y + decoration_up_height;
if (move_flags & ImGuiNavMoveFlags_WrapY) if (move_flags & ImGuiNavMoveFlags_WrapY)
{ {
bb_rel.TranslateX(-bb_rel.GetWidth()); bb_rel.TranslateX(-bb_rel.GetWidth());
@ -10419,7 +10477,7 @@ static void ImGui::NavEndFrame()
} }
if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
{ {
bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y; bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y + decoration_up_height;
if (move_flags & ImGuiNavMoveFlags_WrapY) if (move_flags & ImGuiNavMoveFlags_WrapY)
{ {
bb_rel.TranslateX(+bb_rel.GetWidth()); bb_rel.TranslateX(+bb_rel.GetWidth());
@ -10440,6 +10498,7 @@ static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_UNUSED(g); IM_UNUSED(g);
int order = window->FocusOrder; int order = window->FocusOrder;
IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking)
IM_ASSERT(g.WindowsFocusOrder[order] == window); IM_ASSERT(g.WindowsFocusOrder[order] == window);
return order; return order;
} }
@ -16574,7 +16633,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
if (cfg->ShowStackTool) if (cfg->ShowStackTool)
ShowStackToolWindow(&cfg->ShowStackTool); ShowStackToolWindow(&cfg->ShowStackTool);
if (!Begin("Dear ImGui Metrics/Debugger", p_open)) if (!Begin("Dear ImGui Metrics/Debugger", p_open) || GetCurrentWindow()->BeginCount > 1)
{ {
End(); End();
return; return;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (headers) // (headers)
// Help: // Help:
@ -64,8 +64,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.85 WIP" #define IMGUI_VERSION "1.85"
#define IMGUI_VERSION_NUM 18419 #define IMGUI_VERSION_NUM 18500
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (demo code) // (demo code)
// Help: // Help:

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (drawing and font code) // (drawing and font code)
/* /*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -756,7 +756,7 @@ enum ImGuiItemFlags_
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate item when focused. Currently only used and supported by a few items before it becomes a generic feature. ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
}; };
// Storage for LastItem data // Storage for LastItem data
@ -771,9 +771,7 @@ enum ImGuiItemStatusFlags_
ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag. ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag.
ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
ImGuiItemStatusFlags_FocusedByCode = 1 << 8, // Set when the Focusable item just got focused from code. ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8 // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 9, // Set when the Focusable item just got focused by Tabbing.
ImGuiItemStatusFlags_Focused = ImGuiItemStatusFlags_FocusedByCode | ImGuiItemStatusFlags_FocusedByTabbing
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
, // [imgui_tests only] , // [imgui_tests only]
@ -1239,7 +1237,10 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown) ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
ImGuiNavMoveFlags_Forwarded = 1 << 7, ImGuiNavMoveFlags_Forwarded = 1 << 7,
ImGuiNavMoveFlags_DebugNoResult = 1 << 8 ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
ImGuiNavMoveFlags_Tabbing = 1 << 9, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
ImGuiNavMoveFlags_Activate = 1 << 10,
ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 11 // Do not alter the visible state of keyboard vs mouse nav highlight
}; };
enum ImGuiNavLayer enum ImGuiNavLayer
@ -1255,12 +1256,13 @@ struct ImGuiNavItemData
ImGuiID ID; // Init,Move // Best candidate item ID ImGuiID ID; // Init,Move // Best candidate item ID
ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space
ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags
float DistBox; // Move // Best candidate box distance to current NavId float DistBox; // Move // Best candidate box distance to current NavId
float DistCenter; // Move // Best candidate center distance to current NavId float DistCenter; // Move // Best candidate center distance to current NavId
float DistAxial; // Move // Best candidate axial distance to current NavId float DistAxial; // Move // Best candidate axial distance to current NavId
ImGuiNavItemData() { Clear(); } ImGuiNavItemData() { Clear(); }
void Clear() { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; } void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1766,6 +1768,7 @@ struct ImGuiContext
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring. ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
int NavScoringDebugCount; // Metrics for debugging int NavScoringDebugCount; // Metrics for debugging
int NavTabbingInputableRemaining; // >0 when counting items for tabbing
ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow
ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag)
@ -1781,9 +1784,7 @@ struct ImGuiContext
// Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!) // Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!)
ImGuiWindow* TabFocusRequestCurrWindow; // ImGuiWindow* TabFocusRequestCurrWindow; //
ImGuiWindow* TabFocusRequestNextWindow; // ImGuiWindow* TabFocusRequestNextWindow; //
int TabFocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index
int TabFocusRequestNextCounterRegular; // Stored for next frame
int TabFocusRequestNextCounterTabStop; // " int TabFocusRequestNextCounterTabStop; // "
bool TabFocusPressed; // Set in NewFrame() when user pressed Tab bool TabFocusPressed; // Set in NewFrame() when user pressed Tab
@ -1984,14 +1985,15 @@ struct ImGuiContext
NavMoveKeyMods = ImGuiKeyModFlags_None; NavMoveKeyMods = ImGuiKeyModFlags_None;
NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None; NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
NavScoringDebugCount = 0; NavScoringDebugCount = 0;
NavTabbingInputableRemaining = 0;
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false; NavWindowingToggleLayer = false;
TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL; TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL;
TabFocusRequestCurrCounterRegular = TabFocusRequestCurrCounterTabStop = INT_MAX; TabFocusRequestCurrCounterTabStop = INT_MAX;
TabFocusRequestNextCounterRegular = TabFocusRequestNextCounterTabStop = INT_MAX; TabFocusRequestNextCounterTabStop = INT_MAX;
TabFocusPressed = false; TabFocusPressed = false;
DimBgRatio = 0.0f; DimBgRatio = 0.0f;
@ -2099,7 +2101,6 @@ struct IMGUI_API ImGuiWindowTempData
int CurrentTableIdx; // Current table index (into g.Tables) int CurrentTableIdx; // Current table index (into g.Tables)
ImGuiLayoutType LayoutType; ImGuiLayoutType LayoutType;
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
int FocusCounterRegular; // (Legacy Focus/Tabbing system) Sequential counter, start at -1 and increase when ImGuiItemFlags_Inputable (FIXME-NAV: Needs redesign)
int FocusCounterTabStop; // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through. int FocusCounterTabStop; // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through.
// Local parameters stacks // Local parameters stacks
@ -2711,9 +2712,9 @@ namespace ImGui
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Currently refactoring focus/nav/tabbing system // Currently refactoring focus/nav/tabbing system
// If you have old/custom copy-and-pasted widgets that used FocusableItemRegister(): // If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool focused = FocusableItemRegister(...)' // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)'
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
// (New) IMGUI_VERSION_NUM >= 18411: using 'ItemAdd(..., ImGuiItemAddFlags_Inputable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' // (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || g.NavActivateInputId == id' (WIP)
// Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText()
inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd() inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
@ -2755,6 +2756,7 @@ namespace ImGui
IMGUI_API bool NavMoveRequestButNoResultYet(); IMGUI_API bool NavMoveRequestButNoResultYet();
IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags);
IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags);
IMGUI_API void NavMoveRequestResolveWithLastItem();
IMGUI_API void NavMoveRequestCancel(); IMGUI_API void NavMoveRequestCancel();
IMGUI_API void NavMoveRequestApplyResult(); IMGUI_API void NavMoveRequestApplyResult();
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (tables and columns code) // (tables and columns code)
/* /*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.85 WIP // dear imgui, v1.85
// (widgets code) // (widgets code)
/* /*
@ -2413,17 +2413,17 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active) if (!temp_input_is_active)
{ {
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0; const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]); const bool clicked = (hovered && g.IO.MouseClicked[0]);
const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]); const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id) if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{ {
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
FocusWindow(window); FocusWindow(window);
g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (temp_input_allowed) if (temp_input_allowed)
if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id) if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id)
temp_input_is_active = true; temp_input_is_active = true;
} }
@ -3031,15 +3031,15 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active) if (!temp_input_is_active)
{ {
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0; const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]); const bool clicked = (hovered && g.IO.MouseClicked[0]);
if (focus_requested || clicked || g.NavActivateId == id || g.NavActivateInputId == id) if (input_requested_by_tabbing || clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{ {
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
FocusWindow(window); FocusWindow(window);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id)) if (temp_input_allowed && (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id))
temp_input_is_active = true; temp_input_is_active = true;
} }
} }
@ -4030,21 +4030,19 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// We are only allowed to access the state if we are already the active widget. // We are only allowed to access the state if we are already the active widget.
ImGuiInputTextState* state = GetInputTextState(id); ImGuiInputTextState* state = GetInputTextState(id);
const bool focus_requested_by_code = (item_status_flags & ImGuiItemStatusFlags_FocusedByCode) != 0; const bool input_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
const bool focus_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard));
const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_clicked = hovered && io.MouseClicked[0];
const bool user_nav_input_start = (g.ActiveId != id) && (g.NavActivateInputId == id || g.NavActivateId == id);
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
bool clear_active_id = false; bool clear_active_id = false;
bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline); bool select_all = false;
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX; float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline);
const bool init_make_active = (user_clicked || user_scroll_finish || user_nav_input_start || focus_requested_by_code || focus_requested_by_tabbing); const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_tabbing);
const bool init_state = (init_make_active || user_scroll_active); const bool init_state = (init_make_active || user_scroll_active);
if ((init_state && g.ActiveId != id) || init_changed_specs) if ((init_state && g.ActiveId != id) || init_changed_specs)
{ {
@ -4080,13 +4078,20 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->ID = id; state->ID = id;
state->ScrollX = 0.0f; state->ScrollX = 0.0f;
stb_textedit_initialize_state(&state->Stb, !is_multiline); stb_textedit_initialize_state(&state->Stb, !is_multiline);
if (!is_multiline && focus_requested_by_code) }
if (!is_multiline)
{
if (flags & ImGuiInputTextFlags_AutoSelectAll)
select_all = true;
if (input_requested_by_nav && (!recycle_state || !(g.NavActivateFlags & ImGuiActivateFlags_TryToPreserveState)))
select_all = true;
if (input_requested_by_tabbing || (user_clicked && io.KeyCtrl))
select_all = true; select_all = true;
} }
if (flags & ImGuiInputTextFlags_AlwaysOverwrite) if (flags & ImGuiInputTextFlags_AlwaysOverwrite)
state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863) state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863)
if (!is_multiline && (focus_requested_by_tabbing || (user_clicked && io.KeyCtrl)))
select_all = true;
} }
if (g.ActiveId != id && init_make_active) if (g.ActiveId != id && init_make_active)
@ -4119,7 +4124,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Lock the decision of whether we are going to take the path displaying the cursor or selection // Lock the decision of whether we are going to take the path displaying the cursor or selection
const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active);
bool render_selection = state && state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); bool render_selection = state && (state->HasSelection() || select_all) && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor);
bool value_changed = false; bool value_changed = false;
bool enter_pressed = false; bool enter_pressed = false;
@ -4220,7 +4225,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
if (io.InputQueueCharacters.Size > 0) if (io.InputQueueCharacters.Size > 0)
{ {
if (!ignore_char_inputs && !is_readonly && !user_nav_input_start) if (!ignore_char_inputs && !is_readonly && !input_requested_by_nav)
for (int n = 0; n < io.InputQueueCharacters.Size; n++) for (int n = 0; n < io.InputQueueCharacters.Size; n++)
{ {
// Insert character if they pass filtering // Insert character if they pass filtering
@ -7936,9 +7941,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
if (p_open && !*p_open) if (p_open && !*p_open)
{ {
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true); ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus);
ItemAdd(ImRect(), id);
PopItemFlag();
return false; return false;
} }
@ -8016,9 +8019,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'. // and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
if (tab_appearing && (!tab_bar_appearing || tab_is_new)) if (tab_appearing && (!tab_bar_appearing || tab_is_new))
{ {
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true); ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus);
ItemAdd(ImRect(), id);
PopItemFlag();
if (is_tab_button) if (is_tab_button)
return false; return false;
return tab_contents_visible; return tab_contents_visible;