1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-11-13 18:50:58 +01:00

Merged a bunch of small changes from Docking branch to reduce the difference between branches.

Noticeable: horizontal alignment of CloseButton. Menu fill take account of border. Various stylistic tweaks to accomodate other changes in Docking.
This commit is contained in:
omar 2019-04-16 13:07:43 +02:00
parent 311469e9d6
commit 742b5f4c68
4 changed files with 79 additions and 50 deletions

View File

@ -50,6 +50,7 @@ Other Changes:
- GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero. - GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
- Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood] - Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
- PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485) - PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485)
- Window: Window close button is horizontally aligned with style.FramePadding.x.
- Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert - Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert
to using the ImGui::MemAlloc()/MemFree() calls directly. to using the ImGui::MemAlloc()/MemFree() calls directly.
- Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized

118
imgui.cpp
View File

@ -914,7 +914,7 @@ CODE
(The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse) (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
- You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
contents behind or over every other imgui windows. contents behind or over every other imgui windows (one bg/fg drawlist per viewport).
- You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data. your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
@ -1065,7 +1065,7 @@ static float NavUpdatePageUpPageDown(int allowed_dir_flags);
static inline void NavUpdateAnyRequestFlag(); static inline void NavUpdateAnyRequestFlag();
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id); static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
static ImVec2 NavCalcPreferredRefPos(); static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindow(ImGuiWindow* nav_window); static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
// Misc // Misc
@ -3609,6 +3609,7 @@ void ImGui::NewFrame()
{ {
ImGuiWindow* window = g.Windows[i]; ImGuiWindow* window = g.Windows[i];
window->WasActive = window->Active; window->WasActive = window->Active;
window->BeginCount = 0;
window->Active = false; window->Active = false;
window->WriteAccessed = false; window->WriteAccessed = false;
} }
@ -3791,6 +3792,7 @@ static void AddWindowToDrawData(ImVector<ImDrawList*>* out_render_list, ImGuiWin
} }
} }
// Layer is locked for the root window, however child windows may use a different viewport (e.g. extruding menu)
static void AddRootWindowToDrawData(ImGuiWindow* window) static void AddRootWindowToDrawData(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -4916,6 +4918,13 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
window->Size = window->SizeFull; window->Size = window->SizeFull;
} }
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding)
{
ImGuiContext& g = *GImGui;
ImVec2 size_for_clamping = (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) ? ImVec2(window->Size.x, window->TitleBarHeight()) : window->Size;
window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + size_for_clamping, rect.Min + padding) - size_for_clamping);
}
static void ImGui::RenderOuterBorders(ImGuiWindow* window) static void ImGui::RenderOuterBorders(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -5002,18 +5011,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const int current_frame = g.FrameCount; const int current_frame = g.FrameCount;
const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame);
// Update Flags, LastFrameActive, BeginOrderXXX fields
if (first_begin_of_the_frame)
window->Flags = (ImGuiWindowFlags)flags;
else
flags = window->Flags;
// Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow;
IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
window->HasCloseButton = (p_open != NULL);
// Update the Appearing flag // Update the Appearing flag
bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0); const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0);
@ -5027,9 +5024,28 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (window->Appearing) if (window->Appearing)
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
// Update Flags, LastFrameActive, BeginOrderXXX fields
if (first_begin_of_the_frame)
{
window->Flags = (ImGuiWindowFlags)flags;
window->LastFrameActive = current_frame;
window->BeginOrderWithinParent = 0;
window->BeginOrderWithinContext = (short)(g.WindowsActiveCount++);
}
else
{
flags = window->Flags;
}
// Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow;
IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
// Add to stack // Add to stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
g.CurrentWindowStack.push_back(window); g.CurrentWindowStack.push_back(window);
SetCurrentWindow(window); g.CurrentWindow = NULL;
CheckStacksSize(window, true); CheckStacksSize(window, true);
if (flags & ImGuiWindowFlags_Popup) if (flags & ImGuiWindowFlags_Popup)
{ {
@ -5093,11 +5109,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
UpdateWindowParentAndRootLinks(window, flags, parent_window); UpdateWindowParentAndRootLinks(window, flags, parent_window);
window->Active = true; window->Active = true;
window->BeginOrderWithinParent = 0; window->HasCloseButton = (p_open != NULL);
window->BeginOrderWithinContext = (short)(g.WindowsActiveCount++);
window->BeginCount = 0;
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
window->LastFrameActive = current_frame;
window->IDStack.resize(1); window->IDStack.resize(1);
// Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged). // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged).
@ -5143,7 +5156,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetCurrentWindow(window); SetCurrentWindow(window);
// Lock border size and padding for the frame (so that altering them doesn't cause inconsistencies) // Lock border size and padding for the frame (so that altering them doesn't cause inconsistencies)
window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; if (flags & ImGuiWindowFlags_ChildWindow)
window->WindowBorderSize = style.ChildBorderSize;
else
window->WindowBorderSize = ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize;
window->WindowPadding = style.WindowPadding; window->WindowPadding = style.WindowPadding;
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f)
window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
@ -5247,14 +5263,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Clamp position so it stays visible // Clamp position so it stays visible
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
ImRect viewport_rect(GetViewportRect());
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
{ {
if (g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. if (g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
{ {
ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); ImVec2 clamp_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
ImVec2 size_for_clamping = ((g.IO.ConfigWindowsMoveFromTitleBarOnly) && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) ? ImVec2(window->Size.x, window->TitleBarHeight()) : window->Size; ClampWindowRect(window, viewport_rect, clamp_padding);
window->Pos = ImMax(window->Pos + size_for_clamping, padding) - size_for_clamping;
window->Pos = ImMin(window->Pos, g.IO.DisplaySize - padding);
} }
} }
window->Pos = ImFloor(window->Pos); window->Pos = ImFloor(window->Pos);
@ -5297,7 +5312,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DrawList->Clear(); window->DrawList->Clear();
window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
ImRect viewport_rect(GetViewportRect());
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip)
PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true);
else else
@ -5364,7 +5378,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{ {
ImRect menu_bar_rect = window->MenuBarRect(); ImRect menu_bar_rect = window->MenuBarRect();
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); window->DrawList->AddRectFilled(menu_bar_rect.Min+ImVec2(window_border_size,0), menu_bar_rect.Max-ImVec2(window_border_size,0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top);
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
} }
@ -5485,9 +5499,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Close button // Close button
if (p_open != NULL) if (p_open != NULL)
{ {
const float pad = style.FramePadding.y;
const float rad = g.FontSize * 0.5f; const float rad = g.FontSize * 0.5f;
if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad + 1)) if (CloseButton(window->GetID("#CLOSE"), ImVec2(window->Pos.x + window->Size.x - style.FramePadding.x - rad, window->Pos.y + style.FramePadding.y + rad), rad + 1))
*p_open = false; *p_open = false;
} }
@ -5547,7 +5560,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize)));
window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y); window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y);
// We fill last item data based on Title Bar, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
// This is useful to allow creating context menus on title bar only, etc. // This is useful to allow creating context menus on title bar only, etc.
window->DC.LastItemId = window->MoveId; window->DC.LastItemId = window->MoveId;
window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
@ -5557,6 +5570,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
IMGUI_TEST_ENGINE_ITEM_ADD(window->DC.LastItemRect, window->DC.LastItemId); IMGUI_TEST_ENGINE_ITEM_ADD(window->DC.LastItemRect, window->DC.LastItemId);
#endif #endif
} }
else
{
// Append
SetCurrentWindow(window);
}
PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
@ -7126,14 +7144,6 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
} }
ImRect ImGui::GetWindowAllowedExtentRect(ImGuiWindow*)
{
ImVec2 padding = GImGui->Style.DisplaySafeAreaPadding;
ImRect r_screen = GetViewportRect();
r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f));
return r_screen;
}
// r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.)
// r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it.
ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy) ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy)
@ -7189,6 +7199,15 @@ ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& s
return pos; return pos;
} }
ImRect ImGui::GetWindowAllowedExtentRect(ImGuiWindow* window)
{
IM_UNUSED(window);
ImVec2 padding = GImGui->Style.DisplaySafeAreaPadding;
ImRect r_screen = GetViewportRect();
r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f));
return r_screen;
}
ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -7530,7 +7549,9 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
} }
} }
static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window) // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
// This way we could find the last focused window among our children. It would be much less confusing this way?
static void ImGui::NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window)
{ {
ImGuiWindow* parent_window = nav_window; ImGuiWindow* parent_window = nav_window;
while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
@ -7539,7 +7560,8 @@ static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window)
parent_window->NavLastChildNavWindow = nav_window; parent_window->NavLastChildNavWindow = nav_window;
} }
// Call when we are expected to land on Layer 0 after FocusWindow() // Restore the last focused child.
// Call when we are expected to land on the Main Layer (0) after FocusWindow()
static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window) static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
{ {
return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window; return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window;
@ -7767,7 +7789,7 @@ static void ImGui::NavUpdate()
// Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0
if (g.NavWindow) if (g.NavWindow)
NavSaveLastChildNavWindow(g.NavWindow); NavSaveLastChildNavWindowIntoParent(g.NavWindow);
if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0) if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0)
g.NavWindow->NavLastChildNavWindow = NULL; g.NavWindow->NavLastChildNavWindow = NULL;
@ -8166,7 +8188,9 @@ static void ImGui::NavUpdateWindowing()
// Keyboard: Press and Release ALT to toggle menu layer // Keyboard: Press and Release ALT to toggle menu layer
// FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of back-end clearing releases all keys on ALT-TAB // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of back-end clearing releases all keys on ALT-TAB
if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && IsNavInputPressed(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released)) if (IsNavInputPressed(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Pressed))
g.NavWindowingToggleLayer = true;
if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputPressed(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev)) if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
apply_toggle_layer = true; apply_toggle_layer = true;
@ -8212,7 +8236,8 @@ static void ImGui::NavUpdateWindowing()
{ {
// Move to parent menu if necessary // Move to parent menu if necessary
ImGuiWindow* new_nav_window = g.NavWindow; ImGuiWindow* new_nav_window = g.NavWindow;
while ((new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 while (new_nav_window->ParentWindow
&& (new_nav_window->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) == 0
&& (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0
&& (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
new_nav_window = new_nav_window->ParentWindow; new_nav_window = new_nav_window->ParentWindow;
@ -8224,7 +8249,10 @@ static void ImGui::NavUpdateWindowing()
} }
g.NavDisableHighlight = false; g.NavDisableHighlight = false;
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
NavRestoreLayer((g.NavWindow->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main);
// When entering a regular menu bar with the Alt key, we always reinitialize the navigation ID.
const ImGuiNavLayer new_nav_layer = (g.NavWindow->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main;
NavRestoreLayer(new_nav_layer);
} }
} }
@ -9515,7 +9543,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
} }
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
if (show_draw_cmd_clip_rects && ImGui::IsItemHovered()) if (show_draw_cmd_clip_rects && fg_draw_list && ImGui::IsItemHovered())
{ {
ImRect clip_rect = pcmd->ClipRect; ImRect clip_rect = pcmd->ClipRect;
ImRect vtxs_rect; ImRect vtxs_rect;
@ -9544,7 +9572,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
(n == 0) ? "idx" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); (n == 0) ? "idx" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
} }
ImGui::Selectable(buf, false); ImGui::Selectable(buf, false);
if (ImGui::IsItemHovered()) if (fg_draw_list && ImGui::IsItemHovered())
{ {
ImDrawListFlags backup_flags = fg_draw_list->Flags; ImDrawListFlags backup_flags = fg_draw_list->Flags;
fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.

View File

@ -4267,16 +4267,16 @@ void ShowExampleAppDocuments(bool* p_open)
{ {
static ExampleAppDocuments app; static ExampleAppDocuments app;
// Options
static bool opt_reorderable = true;
static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_;
if (!ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar)) if (!ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar))
{ {
ImGui::End(); ImGui::End();
return; return;
} }
// Options
static bool opt_reorderable = true;
static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_;
// Menu // Menu
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {

View File

@ -1221,7 +1221,7 @@ struct IMGUI_API ImGuiWindow
bool WantCollapseToggle; bool WantCollapseToggle;
bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
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 (== (HiddenFrames*** > 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)
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
short 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)