Merge branch 'viewport' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
omar 2018-12-06 16:36:17 +01:00
commit f768727284
8 changed files with 131 additions and 85 deletions

View File

@ -74,6 +74,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it. - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
- input text: what's the easiest way to implement a nice IP/Mac address input editor? - input text: what's the easiest way to implement a nice IP/Mac address input editor?
- input text: Global callback system so user can plug in an expression evaluator easily.
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: support for cut/paste without selection (cut/paste the current line) - input text multi-line: support for cut/paste without selection (cut/paste the current line)
- input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200)
@ -278,8 +279,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before font has been built. - font: fix AddRemapChar() to work before font has been built.
- font: (api breaking) removed "TTF" from symbol names. also because it now supports OTF. - font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping(). - nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
- nav: patterns to make it possible for arrows key to update selection - nav: patterns to make it possible for arrows key to update selection
- nav: restore/find nearest navid when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) - nav: restore/find nearest navid when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
@ -291,8 +295,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child - nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child
- nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..). - nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..).
- nav: Left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?) - nav: Left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?)
- nav: menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons. - nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons.
- nav: menus: allow pressing Menu to leave a sub-menu. - nav/menus: allow pressing Menu to leave a sub-menu.
- nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB)
- nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it?
- nav: simulate right-click or context activation? (SHIFT+F10) - nav: simulate right-click or context activation? (SHIFT+F10)
- nav: tabs should go through most/all widgets (in submission order?). - nav: tabs should go through most/all widgets (in submission order?).
- nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering. - nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.

View File

@ -141,7 +141,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
#if GLFW_HAS_GLFW_HOVERED #if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy) io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy)
#endif #endif
io.BackendPlatformName = "imgui_impl_glfw"; io.BackendPlatformName = "imgui_impl_glfw";
@ -264,14 +264,32 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons()
{ {
double mouse_x, mouse_y; double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y); glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x + viewport->Pos.x, (float)mouse_y + viewport->Pos.y); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
int window_x, window_y;
glfwGetWindowPos(window, &window_x, &window_y);
io.MousePos = ImVec2((float)mouse_x + window_x, (float)mouse_y + window_y);
}
else
{
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
}
} }
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0; io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0;
} }
#if GLFW_HAS_GLFW_HOVERED // (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because
// - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows).
// - This is _regardless_ of whether another viewport is focused or being dragged from.
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the back-end, imgui will ignore this field and infer the information by relying on the
// rectangles and last focused time of every viewports it knows about. It will be unaware of other windows that may be sitting between or over your windows.
// [GLFW] FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
#if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs)) if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs))
io.MouseHoveredViewport = viewport->ID; io.MouseHoveredViewport = viewport->ID;
#endif #endif

View File

@ -264,16 +264,20 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
SDL_Window* focused_window = SDL_GetKeyboardFocus(); SDL_Window* focused_window = SDL_GetKeyboardFocus();
if (focused_window) if (focused_window)
{ {
// SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
// The creation of new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. {
int wx, wy; // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
SDL_GetWindowPosition(focused_window, &wx, &wy);
SDL_GetGlobalMouseState(&mx, &my); SDL_GetGlobalMouseState(&mx, &my);
mx -= wx; if (ImGui::FindViewportByPlatformHandle((void*)focused_window) != NULL)
my -= wy; io.MousePos = ImVec2((float)mx, (float)my);
}
else
{
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
if (focused_window == g_Window)
io.MousePos = ImVec2((float)mx, (float)my);
}
} }
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)focused_window))
io.MousePos = ImVec2(viewport->Pos.x + (float)mx, viewport->Pos.y + (float)my);
// We already retrieve global mouse position, SDL_CaptureMouse() also let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't trigger the OS window resize cursor // We already retrieve global mouse position, SDL_CaptureMouse() also let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't trigger the OS window resize cursor
// The function is only supported from SDL 2.0.4 (released Jan 2016) // The function is only supported from SDL 2.0.4 (released Jan 2016)

View File

@ -135,21 +135,14 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
return true; return true;
} }
// This code supports multiple OS Windows mapped into different ImGui viewports, // This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
// Because of that, it is a little more complicated than your typical single-viewport binding code. // Because of that, it is a little more complicated than your typical single-viewport binding code!
// A) In Single-viewport mode imgui needs:
// - io.MousePos ............... mouse position, in client window coordinates (what you'd get from GetCursorPos+ScreenToClient() or from WM_MOUSEMOVE)
// io.MousePos is (0,0) when the mouse is on the upper-left corner of the application window.
// B) In Multi-viewport mode imgui needs: (when ImGuiConfigFlags_ViewportsEnable is set)
// - io.MousePos ............... mouse position, in OS absolute coordinates (what you'd get from GetCursorPos(), or from WM_MOUSEMOVE+viewport->Pos).
// io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor.
// - io.MouseHoveredViewport ... [optional] viewport which mouse is hovering, with _VERY_ specific and strict conditions (Read comments next to io.MouseHoveredViewport. This is _NOT_ easy to provide in many high-level engine because of how we use the ImGuiViewportFlags_NoInputs flag)
static void ImGui_ImplWin32_UpdateMousePos() static void ImGui_ImplWin32_UpdateMousePos()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// (When multi-viewports are enabled, all imgui positions are same as OS positions.) // (When multi-viewports are enabled, all imgui positions are same as OS positions)
if (io.WantSetMousePos) if (io.WantSetMousePos)
{ {
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
@ -161,21 +154,39 @@ static void ImGui_ImplWin32_UpdateMousePos()
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
// Set mouse position and viewport // Set imgui mouse position
// (Note that ScreenToClient() and adding +viewport->Pos are mutually cancelling each others when we have multi-viewport enabled. In single-viewport mode, viewport->Pos will be zero) POINT mouse_screen_pos;
POINT pos; if (!::GetCursorPos(&mouse_screen_pos))
if (!::GetCursorPos(&pos))
return; return;
if (HWND focused_hwnd = ::GetActiveWindow()) if (HWND focused_hwnd = ::GetActiveWindow())
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)focused_hwnd))
{ {
POINT client_pos = pos; if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
::ScreenToClient(focused_hwnd, &client_pos); {
io.MousePos = ImVec2(viewport->Pos.x + (float)client_pos.x, viewport->Pos.y + (float)client_pos.y); // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
// This is the position you can get with GetCursorPos(). In theory adding viewport->Pos is also the reverse operation of doing ScreenToClient().
if (ImGui::FindViewportByPlatformHandle((void*)focused_hwnd) != NULL)
io.MousePos = ImVec2((float)mouse_screen_pos.x, (float)mouse_screen_pos.y);
}
else
{
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window.)
// This is the position you can get with GetCursorPos() + ScreenToClient() or from WM_MOUSEMOVE.
if (focused_hwnd == g_hWnd)
{
POINT mouse_client_pos = mouse_screen_pos;
::ScreenToClient(focused_hwnd, &mouse_client_pos);
io.MousePos = ImVec2((float)mouse_client_pos.x, (float)mouse_client_pos.y);
}
}
} }
// Our back-end can tell which window is under the mouse cursor (not every back-end can), so pass that info to imgui // (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
if (HWND hovered_hwnd = ::WindowFromPoint(pos)) // Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because
// - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows).
// - This is _regardless_ of whether another viewport is focused or being dragged from.
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the back-end, imgui will ignore this field and infer the information by relying on the
// rectangles and last focused time of every viewports it knows about. It will be unaware of other windows that may be sitting between or over your windows.
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd)) if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
io.MouseHoveredViewport = viewport->ID; io.MouseHoveredViewport = viewport->ID;
} }

View File

@ -2544,7 +2544,7 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
IM_ASSERT(id != 0); IM_ASSERT(id != 0);
// Assume that SetFocusID() is called in the context where its NavLayer is the current layer, which is the case everywhere we call it. // Assume that SetFocusID() is called in the context where its NavLayer is the current layer, which is the case everywhere we call it.
const int nav_layer = window->DC.NavLayerCurrent; const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
if (g.NavWindow != window) if (g.NavWindow != window)
g.NavInitRequest = false; g.NavInitRequest = false;
g.NavId = id; g.NavId = id;
@ -4511,14 +4511,14 @@ static void CheckStacksSize(ImGuiWindow* window, bool write)
{ {
// NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
int* p_backup = &window->DC.StackSizesBackup[0]; short* p_backup = &window->DC.StackSizesBackup[0];
{ int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop() { int current = window->IDStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop()
{ int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup() { int current = window->DC.GroupStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup()
{ int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup() { int current = g.CurrentPopupStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup()
// For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them. // For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them.
{ int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() { int current = g.ColorModifiers.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup >= current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor()
{ int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() { int current = g.StyleModifiers.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup >= current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar()
{ int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont() { int current = g.FontStack.Size; if (write) *p_backup = (short)current; else IM_ASSERT(*p_backup >= current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont()
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
} }
@ -4972,7 +4972,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Flags = (ImGuiWindowFlags)flags; window->Flags = (ImGuiWindowFlags)flags;
window->LastFrameActive = current_frame; window->LastFrameActive = current_frame;
window->BeginOrderWithinParent = 0; window->BeginOrderWithinParent = 0;
window->BeginOrderWithinContext = g.WindowsActiveCount++; window->BeginOrderWithinContext = (short)(g.WindowsActiveCount++);
} }
else else
{ {
@ -5213,7 +5213,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Position child window // Position child window
if (flags & ImGuiWindowFlags_ChildWindow) if (flags & ImGuiWindowFlags_ChildWindow)
{ {
window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; window->BeginOrderWithinParent = (short)parent_window->DC.ChildWindows.Size;
parent_window->DC.ChildWindows.push_back(window); parent_window->DC.ChildWindows.push_back(window);
if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip)
window->Pos = parent_window->DC.CursorPos; window->Pos = parent_window->DC.CursorPos;
@ -5496,7 +5496,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.CurrentLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrentLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
window->DC.NavHideHighlightOneFrame = false; window->DC.NavHideHighlightOneFrame = false;
window->DC.NavHasScroll = (GetScrollMaxY() > 0.0f); window->DC.NavHasScroll = (GetWindowScrollMaxY(window) > 0.0f);
window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext;
window->DC.NavLayerActiveMaskNext = 0x00; window->DC.NavLayerActiveMaskNext = 0x00;
window->DC.MenuBarAppending = false; window->DC.MenuBarAppending = false;
@ -5552,8 +5552,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Close & collapse button are on layer 1 (same as menus) and don't default focus // Close & collapse button are on layer 1 (same as menus) and don't default focus
const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus;
window->DC.NavLayerCurrent++; window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
window->DC.NavLayerCurrentMask <<= 1; window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
// Collapse button // Collapse button
if (!(flags & ImGuiWindowFlags_NoCollapse)) if (!(flags & ImGuiWindowFlags_NoCollapse))
@ -5568,8 +5568,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
*p_open = false; *p_open = false;
} }
window->DC.NavLayerCurrent--; window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
window->DC.NavLayerCurrentMask >>= 1; window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
window->DC.ItemFlags = item_flags_backup; window->DC.ItemFlags = item_flags_backup;
// Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker) // Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
@ -5807,7 +5807,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
g.NavInitRequest = false; g.NavInitRequest = false;
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
g.NavIdIsAlive = false; g.NavIdIsAlive = false;
g.NavLayer = 0; g.NavLayer = ImGuiNavLayer_Main;
//IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL); //IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL);
} }
@ -8386,7 +8386,7 @@ static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window; return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window;
} }
static void NavRestoreLayer(int layer) static void NavRestoreLayer(ImGuiNavLayer layer)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.NavLayer = layer; g.NavLayer = layer;
@ -8643,7 +8643,7 @@ static void ImGui::NavUpdate()
else if (g.NavLayer != 0) else if (g.NavLayer != 0)
{ {
// Leave the "menu" layer // Leave the "menu" layer
NavRestoreLayer(0); NavRestoreLayer(ImGuiNavLayer_Main);
} }
else else
{ {
@ -9028,8 +9028,8 @@ static void ImGui::NavUpdateWindowing()
NavInitWindow(apply_focus_window, false); NavInitWindow(apply_focus_window, false);
// If the window only has a menu layer, select it directly // If the window only has a menu layer, select it directly
if (apply_focus_window->DC.NavLayerActiveMask == (1 << 1)) if (apply_focus_window->DC.NavLayerActiveMask == (1 << ImGuiNavLayer_Menu))
g.NavLayer = 1; g.NavLayer = ImGuiNavLayer_Menu;
// Request OS level focus // Request OS level focus
if (apply_focus_window->Viewport != previous_viewport && g.PlatformIO.Platform_SetWindowFocus) if (apply_focus_window->Viewport != previous_viewport && g.PlatformIO.Platform_SetWindowFocus)
@ -9058,10 +9058,10 @@ static void ImGui::NavUpdateWindowing()
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
// When entering a regular menu bar with the Alt key, we always reinitialize the navigation ID. It however persist on docking tab tabs. // When entering a regular menu bar with the Alt key, we always reinitialize the navigation ID. It however persist on docking tab tabs.
const int new_nav_layer = (g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) ? (g.NavLayer ^ 1) : 0; const ImGuiNavLayer new_nav_layer = (g.NavWindow->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main;
const bool preserve_layer_1_nav_id = (new_nav_window->DockNodeAsHost != NULL); const bool preserve_layer_1_nav_id = (new_nav_window->DockNodeAsHost != NULL);
if (new_nav_layer == 1 && !preserve_layer_1_nav_id) if (new_nav_layer == ImGuiNavLayer_Menu && !preserve_layer_1_nav_id)
g.NavWindow->NavLastIds[1] = 0; g.NavWindow->NavLastIds[ImGuiNavLayer_Menu] = 0;
NavRestoreLayer(new_nav_layer); NavRestoreLayer(new_nav_layer);
} }
} }
@ -11019,8 +11019,8 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
if (!node->IsDockSpace) if (!node->IsDockSpace)
{ {
host_window->SkipItems = false; host_window->SkipItems = false;
host_window->DC.NavLayerCurrent++; host_window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
host_window->DC.NavLayerCurrentMask <<= 1; host_window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
} }
PushID(node->ID); PushID(node->ID);
@ -11209,8 +11209,8 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
// Restore SkipItems flag // Restore SkipItems flag
if (!node->IsDockSpace) if (!node->IsDockSpace)
{ {
host_window->DC.NavLayerCurrent--; host_window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
host_window->DC.NavLayerCurrentMask >>= 1; host_window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
host_window->SkipItems = backup_skip_item; host_window->SkipItems = backup_skip_item;
} }
} }

View File

@ -45,7 +45,7 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY00 then bounced up to XYY01 when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY00 then bounced up to XYY01 when release tagging happens)
#define IMGUI_VERSION "1.66b" #define IMGUI_VERSION "1.67 WIP"
#define IMGUI_VERSION_NUM 16602 #define IMGUI_VERSION_NUM 16602
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert))
#define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch #define IMGUI_HAS_VIEWPORT 1 // Viewport WIP branch
@ -1316,7 +1316,7 @@ struct ImGuiIO
bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API.
float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text.
float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends.
ImGuiID MouseHoveredViewport; // (Optional) When using multiple viewports: viewport the OS mouse cursor is hovering _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag, and _REGARDLESS_ of whether another viewport is focused. Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will use a decent heuristic instead. ImGuiID MouseHoveredViewport; // (Optional) When using multiple viewports: viewport the OS mouse cursor is hovering _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag, and _REGARDLESS_ of whether another viewport is focused. Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows).
bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift bool KeyShift; // Keyboard modifier pressed: Shift
bool KeyAlt; // Keyboard modifier pressed: Alt bool KeyAlt; // Keyboard modifier pressed: Alt

View File

@ -408,13 +408,20 @@ enum ImGuiNavForward
ImGuiNavForward_ForwardActive ImGuiNavForward_ForwardActive
}; };
enum ImGuiNavLayer
{
ImGuiNavLayer_Main = 0, // Main scrolling layer
ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu)
ImGuiNavLayer_COUNT
};
enum ImGuiPopupPositionPolicy enum ImGuiPopupPositionPolicy
{ {
ImGuiPopupPositionPolicy_Default, ImGuiPopupPositionPolicy_Default,
ImGuiPopupPositionPolicy_ComboBox ImGuiPopupPositionPolicy_ComboBox
}; };
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D and maintenance of some patches) // 1D vector (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
struct ImVec1 struct ImVec1
{ {
float x; float x;
@ -892,7 +899,7 @@ struct ImGuiContext
float NavWindowingTimer; float NavWindowingTimer;
float NavWindowingHighlightAlpha; float NavWindowingHighlightAlpha;
bool NavWindowingToggleLayer; bool NavWindowingToggleLayer;
int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later.
int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid
bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
@ -1038,7 +1045,7 @@ struct ImGuiContext
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingList = NULL; NavWindowingTarget = NavWindowingTargetAnim = NavWindowingList = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false; NavWindowingToggleLayer = false;
NavLayer = 0; NavLayer = ImGuiNavLayer_Main;
NavIdTabCounter = INT_MAX; NavIdTabCounter = INT_MAX;
NavIdIsAlive = false; NavIdIsAlive = false;
NavMousePosDirty = false; NavMousePosDirty = false;
@ -1119,12 +1126,12 @@ struct IMGUI_API ImGuiWindowTempData
ImGuiItemStatusFlags LastItemStatusFlags; ImGuiItemStatusFlags LastItemStatusFlags;
ImRect LastItemRect; // Interaction rect ImRect LastItemRect; // Interaction rect
ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect)
bool NavHideHighlightOneFrame; ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
int NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
int NavLayerCurrentMask; // = (1 << NavLayerCurrent) used by ItemAdd prior to clipping. int NavLayerCurrentMask; // = (1 << NavLayerCurrent) used by ItemAdd prior to clipping.
int NavLayerActiveMask; // Which layer have been written to (result from previous frame) int NavLayerActiveMask; // Which layer have been written to (result from previous frame)
int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame) int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame)
bool NavHideHighlightOneFrame;
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
bool MenuBarAppending; // FIXME: Remove this bool MenuBarAppending; // FIXME: Remove this
ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs. ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs.
ImVector<ImGuiWindow*> ChildWindows; ImVector<ImGuiWindow*> ChildWindows;
@ -1140,7 +1147,7 @@ struct IMGUI_API ImGuiWindowTempData
ImVector<float> ItemWidthStack; ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack; ImVector<float> TextWrapPosStack;
ImVector<ImGuiGroupData>GroupStack; ImVector<ImGuiGroupData>GroupStack;
int StackSizesBackup[6]; // Store size of various stacks for asserting short StackSizesBackup[6]; // Store size of various stacks for asserting
ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
ImVec1 GroupOffset; ImVec1 GroupOffset;
@ -1158,11 +1165,11 @@ struct IMGUI_API ImGuiWindowTempData
LastItemId = 0; LastItemId = 0;
LastItemStatusFlags = 0; LastItemStatusFlags = 0;
LastItemRect = LastItemDisplayRect = ImRect(); LastItemRect = LastItemDisplayRect = ImRect();
NavLayerActiveMask = NavLayerActiveMaskNext = 0x00;
NavLayerCurrent = ImGuiNavLayer_Main;
NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
NavHideHighlightOneFrame = false; NavHideHighlightOneFrame = false;
NavHasScroll = false; NavHasScroll = false;
NavLayerActiveMask = NavLayerActiveMaskNext = 0x00;
NavLayerCurrent = 0;
NavLayerCurrentMask = 1 << 0;
MenuBarAppending = false; MenuBarAppending = false;
MenuBarOffset = ImVec2(0.0f, 0.0f); MenuBarOffset = ImVec2(0.0f, 0.0f);
StateStorage = NULL; StateStorage = NULL;
@ -1215,9 +1222,9 @@ struct IMGUI_API ImGuiWindow
bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
bool Hidden; // Do not display (== (HiddenFramesForResize > 0) || bool Hidden; // Do not display (== (HiddenFramesForResize > 0) ||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL) bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues. short BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
int AutoFitFramesX, AutoFitFramesY; int AutoFitFramesX, AutoFitFramesY;
bool AutoFitOnlyGrows; bool AutoFitOnlyGrows;
@ -1258,8 +1265,8 @@ struct IMGUI_API ImGuiWindow
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag. ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.) ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.)
ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1) ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
ImRect NavRectRel[2]; // Reference rectangle, in window relative space ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space
// Navigation / Focus // Navigation / Focus
// FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext // FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext

View File

@ -5529,8 +5529,8 @@ bool ImGui::BeginMenuBar()
window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y); window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.NavLayerCurrent++; window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
window->DC.NavLayerCurrentMask <<= 1; window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
window->DC.MenuBarAppending = true; window->DC.MenuBarAppending = true;
AlignTextToFramePadding(); AlignTextToFramePadding();
return true; return true;
@ -5556,7 +5556,7 @@ void ImGui::EndMenuBar()
IM_ASSERT(window->DC.NavLayerActiveMaskNext & 0x02); // Sanity check IM_ASSERT(window->DC.NavLayerActiveMaskNext & 0x02); // Sanity check
FocusWindow(window); FocusWindow(window);
SetNavIDWithRectRel(window->NavLastIds[1], 1, window->NavRectRel[1]); SetNavIDWithRectRel(window->NavLastIds[1], 1, window->NavRectRel[1]);
g.NavLayer = 1; g.NavLayer = ImGuiNavLayer_Menu;
g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
NavMoveRequestCancel(); NavMoveRequestCancel();
@ -5571,8 +5571,8 @@ void ImGui::EndMenuBar()
window->DC.GroupStack.back().AdvanceCursor = false; window->DC.GroupStack.back().AdvanceCursor = false;
EndGroup(); // Restore position on layer 0 EndGroup(); // Restore position on layer 0
window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.NavLayerCurrent--; window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
window->DC.NavLayerCurrentMask >>= 1; window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
window->DC.MenuBarAppending = false; window->DC.MenuBarAppending = false;
} }