Docking: Added Docking system. (Part 2) (#351)
This commit is contained in:
parent
bd5b38e232
commit
9ac1e93aa1
465
imgui.cpp
465
imgui.cpp
@ -1067,6 +1067,7 @@ ImGuiIO::ImGuiIO()
|
||||
DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f);
|
||||
|
||||
// Miscellaneous configuration options
|
||||
ConfigDockingWithKeyMod = true;
|
||||
#ifdef __APPLE__
|
||||
ConfigMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag
|
||||
#else
|
||||
@ -2345,7 +2346,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
AutoFitChildAxises = 0x00;
|
||||
AutoPosLastDirection = ImGuiDir_None;
|
||||
HiddenFramesRegular = HiddenFramesForResize = 0;
|
||||
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
|
||||
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
|
||||
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
LastFrameActive = -1;
|
||||
@ -2367,6 +2368,12 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
FocusIdxAllCounter = FocusIdxTabCounter = -1;
|
||||
FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX;
|
||||
FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX;
|
||||
|
||||
DockNode = DockNodeAsHost = NULL;
|
||||
DockId = 0;
|
||||
DockTabItemStatusFlags = 0;
|
||||
DockOrder = -1;
|
||||
DockIsActive = DockTabIsVisible = DockTabWantClose = false;
|
||||
}
|
||||
|
||||
ImGuiWindow::~ImGuiWindow()
|
||||
@ -2656,8 +2663,9 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
if ((window->DC.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
return false;
|
||||
|
||||
// Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect tht case.
|
||||
if (window->DC.LastItemId == window->MoveId && window->WriteAccessed)
|
||||
// Special handling for the dummy item after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if ((window->DC.LastItemId == window->ID || window->DC.LastItemId == window->MoveId) && window->WriteAccessed)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -3042,16 +3050,17 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
// - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame.
|
||||
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
|
||||
FindHoveredWindow();
|
||||
//IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MouseViewport);
|
||||
|
||||
// Modal windows prevents cursor from hovering behind them.
|
||||
ImGuiWindow* modal_window = GetFrontMostPopupModal();
|
||||
if (modal_window)
|
||||
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
|
||||
g.HoveredRootWindow = g.HoveredWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// Disabled mouse?
|
||||
if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
|
||||
int mouse_earliest_button_down = -1;
|
||||
@ -3071,7 +3080,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
|
||||
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
|
||||
if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
|
||||
g.HoveredWindow = g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
|
||||
// Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to imgui + app)
|
||||
if (g.WantCaptureMouseNextFrame != -1)
|
||||
@ -3210,9 +3219,16 @@ void ImGui::NewFrame()
|
||||
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
|
||||
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
||||
|
||||
// Undocking
|
||||
// (needs to be before UpdateMovingWindow so the window is already offset and following the mouse on the detaching frame)
|
||||
DockContextUpdateUndocking(g.DockContext);
|
||||
|
||||
// Find hovered window
|
||||
// (needs to be before UpdateMovingWindow so we fill HoveredWindowUnderMovingWindow on the mouse release frame)
|
||||
UpdateHoveredWindowAndCaptureFlags();
|
||||
|
||||
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
||||
UpdateMouseMovingWindow();
|
||||
UpdateHoveredWindowAndCaptureFlags();
|
||||
|
||||
// Background darkening/whitening
|
||||
if (GetFrontMostPopupModal() != NULL || (g.NavWindowingTarget != NULL && g.NavWindowingHighlightAlpha > 0.0f))
|
||||
@ -3257,6 +3273,9 @@ void ImGui::NewFrame()
|
||||
g.CurrentPopupStack.resize(0);
|
||||
ClosePopupsOverWindow(g.NavWindow);
|
||||
|
||||
// Docking
|
||||
DockContextUpdateDocking(g.DockContext);
|
||||
|
||||
// Create implicit window - we will only render it if the user has added something to it.
|
||||
// We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
|
||||
SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver);
|
||||
@ -3277,6 +3296,10 @@ void ImGui::Initialize(ImGuiContext* context)
|
||||
ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll;
|
||||
g.SettingsHandlers.push_back(ini_handler);
|
||||
|
||||
// Docking Extension
|
||||
IM_ASSERT(g.DockContext == NULL);
|
||||
DockContextInitialize(&g);
|
||||
|
||||
g.Initialized = true;
|
||||
}
|
||||
|
||||
@ -3297,6 +3320,10 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
if (g.SettingsLoaded && g.IO.IniFilename != NULL)
|
||||
SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||
|
||||
// Shutdown Docking extensions
|
||||
IM_ASSERT(g.DockContext != NULL);
|
||||
DockContextShutdown(&g);
|
||||
|
||||
// Clear everything else
|
||||
for (int i = 0; i < g.Windows.Size; i++)
|
||||
IM_DELETE(g.Windows[i]);
|
||||
@ -3306,8 +3333,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.CurrentWindowStack.clear();
|
||||
g.WindowsById.Clear();
|
||||
g.NavWindow = NULL;
|
||||
g.HoveredWindow = NULL;
|
||||
g.HoveredRootWindow = NULL;
|
||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
||||
g.MovingWindow = NULL;
|
||||
g.ColorModifiers.clear();
|
||||
@ -3470,6 +3496,14 @@ void ImGui::PopClipRect()
|
||||
window->ClipRect = window->DrawList->_ClipRectStack.back();
|
||||
}
|
||||
|
||||
static ImGuiWindow* FindFromMostVisibleChildWindow(ImGuiWindow* window)
|
||||
{
|
||||
for (int n = window->DC.ChildWindows.Size - 1; n >= 0; n--)
|
||||
if (IsWindowActiveAndVisible(window->DC.ChildWindows[n]))
|
||||
return FindFromMostVisibleChildWindow(window->DC.ChildWindows[n]);
|
||||
return window;
|
||||
}
|
||||
|
||||
// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
|
||||
void ImGui::EndFrame()
|
||||
{
|
||||
@ -3492,6 +3526,33 @@ void ImGui::EndFrame()
|
||||
g.CurrentWindow->Active = false;
|
||||
End();
|
||||
|
||||
// CTRL-TAB
|
||||
const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL);
|
||||
if (dim_bg_for_window_list)
|
||||
{
|
||||
// Choose a draw list that will be front-most across all our children
|
||||
ImGuiWindow* window = g.NavWindowingTargetAnim;
|
||||
ImDrawList* draw_list = FindFromMostVisibleChildWindow(window->RootWindow)->DrawList;
|
||||
draw_list->PushClipRectFullScreen();
|
||||
|
||||
// Docking: draw modal whitening background on other nodes of a same dock tree
|
||||
if (window->RootWindowDockStop->DockIsActive)
|
||||
if (window->RootWindow != window->RootWindowDockStop)
|
||||
RenderRectFilledWithHole(draw_list, window->RootWindow->Rect(), window->RootWindowDockStop->Rect(), GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio), g.Style.WindowRounding);
|
||||
|
||||
// Draw navigation selection/windowing rectangle border
|
||||
float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding);
|
||||
ImRect bb = window->Rect();
|
||||
bb.Expand(g.FontSize);
|
||||
if (bb.Contains(GetViewportRect())) // If a window fits the entire viewport, adjust its highlight inward
|
||||
{
|
||||
bb.Expand(-g.FontSize - 1.0f);
|
||||
rounding = window->WindowRounding;
|
||||
}
|
||||
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f);
|
||||
draw_list->PopClipRect();
|
||||
}
|
||||
|
||||
// Show CTRL+TAB list
|
||||
if (g.NavWindowingTarget)
|
||||
NavUpdateWindowingList();
|
||||
@ -3701,10 +3762,11 @@ static void FindHoveredWindow()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
ImGuiWindow* hovered_window = NULL;
|
||||
ImGuiWindow* hovered_window_ignoring_moving_window = NULL;
|
||||
if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs))
|
||||
hovered_window = g.MovingWindow;
|
||||
|
||||
for (int i = g.Windows.Size - 1; i >= 0 && hovered_window == NULL; i--)
|
||||
for (int i = g.Windows.Size - 1; i >= 0; i--)
|
||||
{
|
||||
ImGuiWindow* window = g.Windows[i];
|
||||
if (!window->Active || window->Hidden)
|
||||
@ -3718,14 +3780,16 @@ static void FindHoveredWindow()
|
||||
{
|
||||
if (hovered_window == NULL)
|
||||
hovered_window = window;
|
||||
if (hovered_window)
|
||||
if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow))
|
||||
hovered_window_ignoring_moving_window = window;
|
||||
if (hovered_window && hovered_window_ignoring_moving_window)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g.HoveredWindow = hovered_window;
|
||||
g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
|
||||
|
||||
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window;
|
||||
}
|
||||
|
||||
// Test if mouse cursor is hovering given rectangle
|
||||
@ -3951,7 +4015,17 @@ bool ImGui::IsItemDeactivatedAfterEdit()
|
||||
bool ImGui::IsItemFocused()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.NavId && !g.NavDisableHighlight && g.NavId == g.CurrentWindow->DC.LastItemId;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
if (g.NavId == 0 || g.NavDisableHighlight || g.NavId != window->DC.LastItemId)
|
||||
return false;
|
||||
|
||||
// Special handling for the dummy item after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if (window->DC.LastItemId == window->ID && window->WriteAccessed)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui::IsItemClicked(int mouse_button)
|
||||
@ -4030,7 +4104,7 @@ static bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
|
||||
flags |= ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
|
||||
flags |= ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_NoDocking;
|
||||
flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
|
||||
|
||||
// Size
|
||||
@ -4163,6 +4237,13 @@ static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, b
|
||||
window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags);
|
||||
window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags);
|
||||
window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags);
|
||||
window->SetWindowDockAllowFlags = enabled ? (window->SetWindowDockAllowFlags | flags) : (window->SetWindowDockAllowFlags & ~flags);
|
||||
}
|
||||
|
||||
ImGuiWindow* ImGui::FindWindowByID(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id);
|
||||
}
|
||||
|
||||
ImGuiWindow* ImGui::FindWindowByName(const char* name)
|
||||
@ -4195,6 +4276,8 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
window->Collapsed = settings->Collapsed;
|
||||
if (ImLengthSqr(settings->Size) > 0.00001f)
|
||||
size = ImFloor(settings->Size);
|
||||
window->DockId = settings->DockId;
|
||||
window->DockOrder = settings->DockOrder;
|
||||
}
|
||||
window->Size = window->SizeFull = window->SizeFullAtLastBegin = size;
|
||||
window->DC.CursorMaxPos = window->Pos; // So first call to CalcSizeContents() doesn't return crazy values
|
||||
@ -4220,6 +4303,11 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
return window;
|
||||
}
|
||||
|
||||
static ImGuiWindow* GetWindowForTitleAndMenuHeight(ImGuiWindow* window)
|
||||
{
|
||||
return (window->DockNodeAsHost && window->DockNodeAsHost->VisibleWindow) ? window->DockNodeAsHost->VisibleWindow : window;
|
||||
}
|
||||
|
||||
static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -4244,8 +4332,9 @@ static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size)
|
||||
// Minimum size
|
||||
if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
|
||||
{
|
||||
ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
||||
new_size = ImMax(new_size, g.Style.WindowMinSize);
|
||||
new_size.y = ImMax(new_size.y, window->TitleBarHeight() + window->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
||||
new_size.y = ImMax(new_size.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
||||
}
|
||||
return new_size;
|
||||
}
|
||||
@ -4476,7 +4565,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
||||
}
|
||||
|
||||
// Apply back modified position/size to window
|
||||
if (size_target.x != FLT_MAX)
|
||||
if (size_target.x != FLT_MAX && (size_target.x != window->SizeFull.x || size_target.y != window->SizeFull.y))
|
||||
{
|
||||
window->SizeFull = size_target;
|
||||
MarkIniSettingsDirty(window);
|
||||
@ -4493,9 +4582,11 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
||||
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
|
||||
{
|
||||
window->ParentWindow = parent_window;
|
||||
window->RootWindow = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window;
|
||||
window->RootWindow = window->RootWindowDockStop = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window;
|
||||
if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip))
|
||||
window->RootWindow = parent_window->RootWindow;
|
||||
if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip) && !window->DockIsActive)
|
||||
window->RootWindowDockStop = parent_window->RootWindowDockStop;
|
||||
if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)))
|
||||
window->RootWindowForTitleBarHighlight = parent_window->RootWindowForTitleBarHighlight;
|
||||
while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened)
|
||||
@ -4526,6 +4617,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window = CreateNewWindow(name, size_on_first_use, flags);
|
||||
}
|
||||
|
||||
// Update stored window name when it changes (which can only happen with the "###" operator).
|
||||
// Only if it is meant to be displayed to the end user in a different place than the title bar (which already always display the 'name' parameter)
|
||||
bool window_title_visible_elsewhere = (window->DockIsActive);
|
||||
if (!window_just_created && window_title_visible_elsewhere && strcmp(name, window->Name) != 0)
|
||||
{
|
||||
IM_DELETE(window->Name);
|
||||
window->Name = ImStrdup(name);
|
||||
}
|
||||
|
||||
// Automatically disable manual moving/resizing when NoInputs is set
|
||||
if (flags & ImGuiWindowFlags_NoInputs)
|
||||
flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
|
||||
@ -4546,12 +4646,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
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
|
||||
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->HiddenFramesForResize > 0);
|
||||
@ -4565,6 +4659,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if (window->Appearing)
|
||||
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
|
||||
|
||||
// Docking
|
||||
// (NB: during the frame dock nodes are created, it is possible that (window->DockIsActive == false) even though (window->DockNode->Windows.Size > 1)
|
||||
IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL); // Cannot be both
|
||||
if (g.NextWindowData.DockCond)
|
||||
SetWindowDock(window, g.NextWindowData.DockId, g.NextWindowData.DockCond);
|
||||
if (first_begin_of_the_frame && (window->DockId != 0 || window->DockNode != NULL))
|
||||
{
|
||||
BeginDocked(window, p_open);
|
||||
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 = window->DockIsActive ? window->DockNode->HostWindow : 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
|
||||
g.CurrentWindowStack.push_back(window);
|
||||
SetCurrentWindow(window);
|
||||
@ -4631,6 +4741,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
UpdateWindowParentAndRootLinks(window, flags, parent_window);
|
||||
|
||||
window->Active = true;
|
||||
window->HasCloseButton = (p_open != NULL);
|
||||
window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
|
||||
window->LastFrameActive = current_frame;
|
||||
window->IDStack.resize(1);
|
||||
@ -4666,16 +4777,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
SetCurrentWindow(window);
|
||||
|
||||
// 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;
|
||||
window->WindowPadding = style.WindowPadding;
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f)
|
||||
if (window->DockIsActive)
|
||||
window->WindowBorderSize = 0.0f;
|
||||
else if (flags & ImGuiWindowFlags_ChildWindow)
|
||||
window->WindowBorderSize = style.ChildBorderSize;
|
||||
else
|
||||
window->WindowBorderSize = ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize;
|
||||
if (!window->DockIsActive && (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);
|
||||
else
|
||||
window->WindowPadding = style.WindowPadding;
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
|
||||
// Collapse window by double-clicking on title bar
|
||||
// At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse))
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse) && !window->DockIsActive)
|
||||
{
|
||||
// We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar.
|
||||
ImRect title_bar_rect = window->TitleBarRect();
|
||||
@ -4719,6 +4836,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
|
||||
//if (window->DockNode && window->DockIsActive)
|
||||
// size_full_modified = window->SizeFull;
|
||||
|
||||
// Apply minimum/maximum window size constraints and final size
|
||||
window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull);
|
||||
window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull;
|
||||
@ -4768,14 +4888,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->Pos = FindBestWindowPosForPopup(window);
|
||||
|
||||
// Clamp position so it stays visible
|
||||
if (!(flags & ImGuiWindowFlags_ChildWindow))
|
||||
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
|
||||
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
||||
{
|
||||
if (!window_pos_set_by_api && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && 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);
|
||||
window->Pos = ImMax(window->Pos + window->Size, padding) - window->Size;
|
||||
window->Pos = ImMin(window->Pos, g.IO.DisplaySize - padding);
|
||||
}
|
||||
ImVec2 clamp_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
|
||||
window->Pos = ImMax(window->Pos + window->Size, clamp_padding) - window->Size;
|
||||
window->Pos = ImMin(window->Pos, g.IO.DisplaySize - clamp_padding);
|
||||
}
|
||||
window->Pos = ImFloor(window->Pos);
|
||||
|
||||
@ -4795,8 +4913,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Apply window focus (new and reactivated windows are moved to front)
|
||||
bool want_focus = false;
|
||||
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup))
|
||||
{
|
||||
if (flags & ImGuiWindowFlags_Popup)
|
||||
want_focus = true;
|
||||
else if ((window->DockIsActive || !(flags & ImGuiWindowFlags_ChildWindow)) && !(flags & ImGuiWindowFlags_Tooltip))
|
||||
want_focus = true;
|
||||
}
|
||||
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
int border_held = -1;
|
||||
@ -4846,7 +4968,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const float window_rounding = window->WindowRounding;
|
||||
const float window_border_size = window->WindowBorderSize;
|
||||
const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
|
||||
const bool title_bar_is_highlight = want_focus || (window_to_highlight && window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight);
|
||||
const bool title_bar_is_highlight = want_focus || (window_to_highlight && (window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight || (window->DockNode && window->DockNode == window_to_highlight->DockNode)));
|
||||
const ImRect title_bar_rect = window->TitleBarRect();
|
||||
if (window->Collapsed)
|
||||
{
|
||||
@ -4862,16 +4984,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Window background
|
||||
ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags));
|
||||
if (g.NextWindowData.BgAlphaCond != 0)
|
||||
{
|
||||
bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT);
|
||||
g.NextWindowData.BgAlphaCond = 0;
|
||||
}
|
||||
window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot);
|
||||
|
||||
// Title bar
|
||||
ImU32 title_bar_col = GetColorU32(window->Collapsed ? ImGuiCol_TitleBgCollapsed : title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
||||
// (when docked, DockNode are drawing their own title bar. Individual windows however do NOT set the _NoTitleBar flag,
|
||||
// in order for their pos/size to be matching their undocking state.)
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
||||
{
|
||||
ImU32 title_bar_col = GetColorU32(window->Collapsed ? ImGuiCol_TitleBgCollapsed : title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
|
||||
window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top);
|
||||
}
|
||||
|
||||
// Menu bar
|
||||
if (flags & ImGuiWindowFlags_MenuBar)
|
||||
@ -4911,7 +5034,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
ImRect border = GetResizeBorderRect(window, border_held, grip_draw_size, 0.0f);
|
||||
window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size));
|
||||
}
|
||||
if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar))
|
||||
if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
||||
window->DrawList->AddLine(title_bar_rect.GetBL() + ImVec2(style.WindowBorderSize, -1), title_bar_rect.GetBR() + ImVec2(-style.WindowBorderSize, -1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
||||
}
|
||||
|
||||
@ -4991,7 +5114,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
}
|
||||
|
||||
// Title bar
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
||||
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
||||
{
|
||||
// Close & collapse button are on layer 1 (same as menus) and don't default focus
|
||||
const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
||||
@ -5007,9 +5130,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Close button
|
||||
if (p_open != NULL)
|
||||
{
|
||||
const float pad = style.FramePadding.y;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -5042,6 +5164,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
||||
window->OuterRectClipped = window->Rect();
|
||||
if (window->DockIsActive)
|
||||
window->OuterRectClipped.Min.y += window->TitleBarHeight();
|
||||
window->OuterRectClipped.ClipWith(window->ClipRect);
|
||||
|
||||
// Pressing CTRL+C while holding on a window copy its content to the clipboard
|
||||
@ -5069,13 +5193,39 @@ 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.y = ImFloor(0.5f + window->InnerMainRect.Max.y);
|
||||
|
||||
// After Begin() we fill the last item / hovered data based on title bar data. It is a standard behavior (to allow creation of context menus on title bar only, etc.).
|
||||
window->DC.LastItemId = window->MoveId;
|
||||
window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
|
||||
window->DC.LastItemRect = title_bar_rect;
|
||||
if (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
// Docking: Dragging a dockable window (or any of its child) turns it into a drag and drop source.
|
||||
// We need to do this _before_ we overwrite window->DC.LastItemId below because BeginAsDockableDragDropSource() also overwrites it.
|
||||
if ((g.ActiveId == window->MoveId) && ((g.IO.ConfigDockingWithKeyMod && g.IO.KeyShift) || (!g.IO.ConfigDockingWithKeyMod)))
|
||||
if ((window->RootWindow->Flags & (ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking)) == 0)
|
||||
BeginAsDockableDragDropSource(window);
|
||||
|
||||
// Docking: Any dockable window can act as a target. For dock node hosts we call BeginAsDockableDragDropTarget() in DockNodeUpdate() instead.
|
||||
if (g.DragDropActive && !(flags & ImGuiWindowFlags_NoDocking))
|
||||
if (g.MovingWindow == NULL || g.MovingWindow->RootWindow != window)
|
||||
if ((window == window->RootWindow) && !(window->Flags & ImGuiWindowFlags_DockNodeHost))
|
||||
BeginAsDockableDragDropTarget(window);
|
||||
}
|
||||
|
||||
// We fill last item data based on Title Bar or 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.
|
||||
if (window->DockIsActive)
|
||||
{
|
||||
window->DC.LastItemId = window->ID;
|
||||
window->DC.LastItemStatusFlags = window->DockTabItemStatusFlags;
|
||||
window->DC.LastItemRect = window->DockTabItemRect;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->DC.LastItemId = window->MoveId;
|
||||
window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
|
||||
window->DC.LastItemRect = title_bar_rect;
|
||||
}
|
||||
}
|
||||
|
||||
PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
|
||||
if (!(flags & ImGuiWindowFlags_DockNodeHost))
|
||||
PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
|
||||
|
||||
// Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused)
|
||||
if (first_begin_of_the_frame)
|
||||
@ -5084,12 +5234,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->BeginCount++;
|
||||
g.NextWindowData.Clear();
|
||||
|
||||
if (window->DockIsActive && !window->DockTabIsVisible)
|
||||
window->HiddenFramesRegular = 1;
|
||||
|
||||
if (flags & ImGuiWindowFlags_ChildWindow)
|
||||
{
|
||||
// Child window can be out of sight and have "negative" clip windows.
|
||||
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
|
||||
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0);
|
||||
|
||||
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
|
||||
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
|
||||
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
|
||||
window->HiddenFramesRegular = 1;
|
||||
@ -5104,7 +5256,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->HiddenFramesRegular = 1;
|
||||
|
||||
// Update the Hidden flag
|
||||
window->Hidden = (window->HiddenFramesRegular > 0) || (window->HiddenFramesForResize);
|
||||
window->Hidden = (window->HiddenFramesRegular > 0) || (window->HiddenFramesForResize > 0);
|
||||
|
||||
// Return false if we don't intend to display anything to allow user to perform an early out optimization
|
||||
window->SkipItems = (window->Collapsed || !window->Active || window->Hidden) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesForResize <= 0;
|
||||
@ -5135,12 +5287,18 @@ void ImGui::End()
|
||||
|
||||
if (window->DC.ColumnsSet != NULL)
|
||||
EndColumns();
|
||||
PopClipRect(); // Inner window clip rectangle
|
||||
if (!(window->Flags & ImGuiWindowFlags_DockNodeHost)) // Pop inner window clip rectangle
|
||||
PopClipRect();
|
||||
|
||||
// Stop logging
|
||||
if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging
|
||||
LogFinish();
|
||||
|
||||
// Docking: report contents sizes to parent to allow for auto-resize
|
||||
if (window->DockNode && window->DockTabIsVisible)
|
||||
if (ImGuiWindow* host_window = window->DockNode->HostWindow) // FIXME-DOCKSPACE
|
||||
host_window->DC.CursorMaxPos = window->DC.CursorMaxPos + window->WindowPadding - host_window->WindowPadding;
|
||||
|
||||
// Pop from window stack
|
||||
g.CurrentWindowStack.pop_back();
|
||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||
@ -5192,7 +5350,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
|
||||
g.NavIdIsAlive = false;
|
||||
g.NavLayer = 0;
|
||||
//printf("[%05d] FocusWindow(\"%s\")\n", g.FrameCount, window ? window->Name : NULL);
|
||||
//IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL);
|
||||
}
|
||||
|
||||
// Passing NULL allow to disable keyboard focus
|
||||
@ -5511,6 +5669,8 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
||||
case ImGuiCol_TabActive: return "TabActive";
|
||||
case ImGuiCol_TabUnfocused: return "TabUnfocused";
|
||||
case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive";
|
||||
case ImGuiCol_DockingPreview: return "DockingPreview";
|
||||
case ImGuiCol_DockingBg: return "DockingBg";
|
||||
case ImGuiCol_PlotLines: return "PlotLines";
|
||||
case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
|
||||
case ImGuiCol_PlotHistogram: return "PlotHistogram";
|
||||
@ -5554,11 +5714,11 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
|
||||
switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows))
|
||||
{
|
||||
case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows:
|
||||
if (g.HoveredRootWindow != g.CurrentWindow->RootWindow)
|
||||
if (g.HoveredWindow == NULL || g.HoveredWindow->RootWindowDockStop != g.CurrentWindow->RootWindowDockStop)
|
||||
return false;
|
||||
break;
|
||||
case ImGuiHoveredFlags_RootWindow:
|
||||
if (g.HoveredWindow != g.CurrentWindow->RootWindow)
|
||||
if (g.HoveredWindow != g.CurrentWindow->RootWindowDockStop)
|
||||
return false;
|
||||
break;
|
||||
case ImGuiHoveredFlags_ChildWindows:
|
||||
@ -5591,9 +5751,9 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
|
||||
switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows))
|
||||
{
|
||||
case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows:
|
||||
return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow;
|
||||
return g.NavWindow && g.NavWindow->RootWindowDockStop == g.CurrentWindow->RootWindowDockStop;
|
||||
case ImGuiFocusedFlags_RootWindow:
|
||||
return g.NavWindow == g.CurrentWindow->RootWindow;
|
||||
return g.NavWindow == g.CurrentWindow->RootWindowDockStop;
|
||||
case ImGuiFocusedFlags_ChildWindows:
|
||||
return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow);
|
||||
default:
|
||||
@ -5601,10 +5761,16 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui::IsWindowDocked()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return (g.CurrentWindow->DockIsActive);
|
||||
}
|
||||
|
||||
// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext)
|
||||
bool ImGui::IsWindowNavFocusable(ImGuiWindow* window)
|
||||
{
|
||||
return window->Active && window == window->RootWindow && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
|
||||
return window->Active && window == window->RootWindowDockStop && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
|
||||
}
|
||||
|
||||
float ImGui::GetWindowWidth()
|
||||
@ -5777,6 +5943,7 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi
|
||||
g.NextWindowData.PosVal = pos;
|
||||
g.NextWindowData.PosPivotVal = pivot;
|
||||
g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always;
|
||||
g.NextWindowData.PosUndock = true;
|
||||
}
|
||||
|
||||
void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond)
|
||||
@ -5824,6 +5991,13 @@ void ImGui::SetNextWindowBgAlpha(float alpha)
|
||||
g.NextWindowData.BgAlphaCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op)
|
||||
}
|
||||
|
||||
void ImGui::SetNextWindowDock(ImGuiID id, ImGuiCond cond)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.NextWindowData.DockCond = cond ? cond : ImGuiCond_Always;
|
||||
g.NextWindowData.DockId = id;
|
||||
}
|
||||
|
||||
// In window space (not screen space!)
|
||||
ImVec2 ImGui::GetContentRegionMax()
|
||||
{
|
||||
@ -6280,7 +6454,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_
|
||||
window->HiddenFramesRegular = 1;
|
||||
ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount);
|
||||
}
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoNav;
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoNav|ImGuiWindowFlags_NoDocking;
|
||||
Begin(window_name, NULL, flags | extra_flags);
|
||||
}
|
||||
|
||||
@ -6494,7 +6668,7 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags)
|
||||
g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values
|
||||
return false;
|
||||
}
|
||||
return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
|
||||
return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_NoDocking);
|
||||
}
|
||||
|
||||
bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
@ -6992,8 +7166,8 @@ static void NavRestoreLayer(int layer)
|
||||
g.NavLayer = layer;
|
||||
if (layer == 0)
|
||||
g.NavWindow = ImGui::NavRestoreLastChildNavWindow(g.NavWindow);
|
||||
if (layer == 0 && g.NavWindow->NavLastIds[0] != 0)
|
||||
ImGui::SetNavIDWithRectRel(g.NavWindow->NavLastIds[0], layer, g.NavWindow->NavRectRel[0]);
|
||||
if (g.NavWindow->NavLastIds[layer] != 0)
|
||||
ImGui::SetNavIDWithRectRel(g.NavWindow->NavLastIds[layer], layer, g.NavWindow->NavRectRel[layer]);
|
||||
else
|
||||
ImGui::NavInitWindow(g.NavWindow, true);
|
||||
}
|
||||
@ -7034,7 +7208,10 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow)
|
||||
{
|
||||
IM_ASSERT(ImGui::IsMousePosValid()); // This will probably trigger at some point, please share your repro!
|
||||
return ImFloor(g.IO.MousePos);
|
||||
}
|
||||
|
||||
// When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item
|
||||
const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer];
|
||||
@ -7215,7 +7392,7 @@ static void ImGui::NavUpdate()
|
||||
{
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow) && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
|
||||
else if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow) && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow && g.NavWindow != g.NavWindow->RootWindowDockStop)
|
||||
{
|
||||
// Exit child window
|
||||
ImGuiWindow* child_window = g.NavWindow;
|
||||
@ -7596,7 +7773,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
}
|
||||
|
||||
// Apply final focus
|
||||
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
|
||||
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindowDockStop))
|
||||
{
|
||||
g.NavDisableHighlight = false;
|
||||
g.NavDisableMouseHover = true;
|
||||
@ -7618,7 +7795,10 @@ static void ImGui::NavUpdateWindowing()
|
||||
{
|
||||
// Move to parent menu if necessary
|
||||
ImGuiWindow* new_nav_window = g.NavWindow;
|
||||
while ((new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
|
||||
while (new_nav_window->ParentWindow
|
||||
&& (new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0
|
||||
&& (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0
|
||||
&& (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
|
||||
new_nav_window = new_nav_window->ParentWindow;
|
||||
if (new_nav_window != g.NavWindow)
|
||||
{
|
||||
@ -7628,7 +7808,13 @@ static void ImGui::NavUpdateWindowing()
|
||||
}
|
||||
g.NavDisableHighlight = false;
|
||||
g.NavDisableMouseHover = true;
|
||||
NavRestoreLayer((g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) ? (g.NavLayer ^ 1) : 0);
|
||||
|
||||
// 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 bool preserve_layer_1_nav_id = (new_nav_window->DockNodeAsHost != NULL);
|
||||
if (new_nav_layer == 1 && !preserve_layer_1_nav_id)
|
||||
g.NavWindow->NavLastIds[1] = 0;
|
||||
NavRestoreLayer(new_nav_layer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7639,6 +7825,8 @@ static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window)
|
||||
return "(Popup)";
|
||||
if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0)
|
||||
return "(Main menu bar)";
|
||||
if (window->DockNodeAsHost)
|
||||
return "(Dock node)";
|
||||
return "(Untitled)";
|
||||
}
|
||||
|
||||
@ -8178,7 +8366,7 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
|
||||
return false;
|
||||
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
|
||||
if (g.HoveredWindowUnderMovingWindow == NULL || window->RootWindow != g.HoveredWindowUnderMovingWindow->RootWindow)
|
||||
return false;
|
||||
IM_ASSERT(id != 0);
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId))
|
||||
@ -8206,7 +8394,7 @@ bool ImGui::BeginDragDropTarget()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
|
||||
if (g.HoveredWindowUnderMovingWindow == NULL || window->RootWindow != g.HoveredWindowUnderMovingWindow->RootWindow)
|
||||
return false;
|
||||
|
||||
const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
|
||||
@ -8663,6 +8851,7 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
|
||||
}
|
||||
ImGui::MemFree(buf);
|
||||
g.SettingsLoaded = true;
|
||||
DockContextOnLoadSettings();
|
||||
}
|
||||
|
||||
void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
|
||||
@ -8711,9 +8900,12 @@ static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
|
||||
ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
|
||||
float x, y;
|
||||
int i;
|
||||
if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y);
|
||||
else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize);
|
||||
else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0);
|
||||
ImU32 u1;
|
||||
if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) { settings->Pos = ImVec2(x, y); }
|
||||
else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) { settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize); }
|
||||
else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); }
|
||||
else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; }
|
||||
else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; }
|
||||
}
|
||||
|
||||
static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
|
||||
@ -8721,6 +8913,8 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
||||
// Gather data from windows that were active during this session
|
||||
// (if a window wasn't opened in this session we preserve its settings)
|
||||
ImGuiContext& g = *imgui_ctx;
|
||||
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
|
||||
return;
|
||||
for (int i = 0; i != g.Windows.Size; i++)
|
||||
{
|
||||
ImGuiWindow* window = g.Windows[i];
|
||||
@ -8736,6 +8930,9 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
||||
IM_ASSERT(settings->ID == window->ID);
|
||||
settings->Pos = window->Pos;
|
||||
settings->Size = window->SizeFull;
|
||||
IM_ASSERT(window->DockNode == NULL || window->DockNode->ID == window->DockId);
|
||||
settings->DockId = window->DockId;
|
||||
settings->DockOrder = window->DockOrder;
|
||||
settings->Collapsed = window->Collapsed;
|
||||
}
|
||||
|
||||
@ -8744,8 +8941,6 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
||||
for (int i = 0; i != g.SettingsWindows.Size; i++)
|
||||
{
|
||||
const ImGuiWindowSettings* settings = &g.SettingsWindows[i];
|
||||
if (settings->Pos.x == FLT_MAX)
|
||||
continue;
|
||||
const char* name = settings->Name;
|
||||
if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
||||
name = p;
|
||||
@ -8753,6 +8948,14 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
|
||||
buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
|
||||
buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
|
||||
buf->appendf("Collapsed=%d\n", settings->Collapsed);
|
||||
if (settings->DockId != 0)
|
||||
{
|
||||
// Write DockId as 4 digits if possible. Automatic DockId are small numbers, but full explicit DockSpace() are full ImGuiID range.
|
||||
if (settings->DockOrder == -1)
|
||||
buf->appendf("DockId=0x%08X\n", settings->DockId);
|
||||
else
|
||||
buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder);
|
||||
}
|
||||
buf->appendf("\n");
|
||||
}
|
||||
}
|
||||
@ -8899,6 +9102,32 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
|
||||
struct Funcs
|
||||
{
|
||||
static void NodeDockNode(ImGuiDockNode* node, const char* label)
|
||||
{
|
||||
ImGui::SetNextTreeNodeOpen(true, ImGuiCond_Once);
|
||||
bool open;
|
||||
if (node->Windows.Size > 0)
|
||||
open = ImGui::TreeNode((void*)(intptr_t)node->ID, "%s 0x%04X%s: %d windows (vis: '%s')", label, node->ID, node->IsVisible ? "" : " (hidden)", node->Windows.Size, node->VisibleWindow ? node->VisibleWindow->Name : "NULL");
|
||||
else
|
||||
open = ImGui::TreeNode((void*)(intptr_t)node->ID, "%s 0x%04X%s: split %s (act: '%s')", label, node->ID, node->IsVisible ? "" : " (hidden)", (node->SplitAxis == ImGuiAxis_X) ? "horizontal" : (node->SplitAxis == ImGuiAxis_Y) ? "vertical" : "n/a", node->VisibleWindow ? node->VisibleWindow->Name : "NULL");
|
||||
if (open)
|
||||
{
|
||||
IM_ASSERT(node->ChildNodes[0] == NULL || node->ChildNodes[0]->ParentNode == node);
|
||||
IM_ASSERT(node->ChildNodes[1] == NULL || node->ChildNodes[1]->ParentNode == node);
|
||||
ImGui::BulletText("Pos (%.0f,%.0f), Size (%.0f, %.0f), LastExplicit (%.0f, %.0f)%s%s",
|
||||
node->Pos.x, node->Pos.y, node->Size.x, node->Size.y,
|
||||
node->LastExplicitSize.x, node->LastExplicitSize.y,
|
||||
node->IsExplicitRoot ? ", IsExplicitRoot " : "", node->IsDocumentRoot ? ", IsDocumentRoot " : "");
|
||||
if (node->ChildNodes[0])
|
||||
NodeDockNode(node->ChildNodes[0], "Child[0]");
|
||||
if (node->ChildNodes[1])
|
||||
NodeDockNode(node->ChildNodes[1], "Child[1]");
|
||||
if (node->TabBar)
|
||||
NodeTabBar(node->TabBar);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
static void NodeTabBar(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
// Previous window list
|
||||
@ -9027,7 +9256,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y);
|
||||
else
|
||||
ImGui::BulletText("NavRectRel[0]: <None>");
|
||||
ImGui::BulletText("DockId: 0x%04X, DockOrder: %d, %s: 0x%p", window->DockId, window->DockOrder, window->DockNodeAsHost ? "DockNodeAsHost" : "DockNode", window->DockNodeAsHost ? window->DockNodeAsHost : window->DockNode);
|
||||
if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
|
||||
if (window->RootWindowDockStop != window->RootWindow) NodeWindow(window->RootWindowDockStop, "RootWindowDockStop");
|
||||
if (window->ParentWindow != NULL) NodeWindow(window->ParentWindow, "ParentWindow");
|
||||
if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
|
||||
if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size))
|
||||
@ -9059,6 +9290,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList");
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size))
|
||||
{
|
||||
for (int i = 0; i < g.OpenPopupStack.Size; i++)
|
||||
@ -9068,17 +9300,93 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.Data.Size))
|
||||
|
||||
if (ImGui::TreeNode("Docking"))
|
||||
{
|
||||
for (int n = 0; n < g.TabBars.Data.Size; n++)
|
||||
Funcs::NodeTabBar(g.TabBars.GetByIndex(n));
|
||||
ImGuiDockContext* ctx = g.DockContext;
|
||||
static bool show_window_dock_info = false;
|
||||
ImGui::Checkbox("Ctrl shows window dock info", &show_window_dock_info);
|
||||
|
||||
if (ImGui::TreeNode("Dock nodes"))
|
||||
{
|
||||
if (ImGui::SmallButton("Clear settings")) { DockContextClearNodes(ctx, true); }
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Rebuild all")) { ctx->WantFullRebuild = true; }
|
||||
for (int n = 0; n < ctx->Nodes.Data.Size; n++)
|
||||
if (ImGuiDockNode* node = (ImGuiDockNode*)ctx->Nodes.Data[n].val_p)
|
||||
if (node->IsRootNode())
|
||||
Funcs::NodeDockNode(node, "Node");
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.Data.Size))
|
||||
{
|
||||
for (int n = 0; n < g.TabBars.Data.Size; n++)
|
||||
Funcs::NodeTabBar(g.TabBars.GetByIndex(n));
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Settings"))
|
||||
{
|
||||
if (ImGui::SmallButton("Refresh"))
|
||||
SaveIniSettingsToMemory();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Save to disk"))
|
||||
SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Docked Windows:");
|
||||
for (int n = 0; n < g.SettingsWindows.Size; n++)
|
||||
if (g.SettingsWindows[n].DockId != 0)
|
||||
ImGui::BulletText("Window '%s' -> DockId %08X", g.SettingsWindows[n].Name, g.SettingsWindows[n].DockId);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Dock Nodes:");
|
||||
for (int n = 0; n < ctx->SettingsNodes.Size; n++)
|
||||
{
|
||||
ImGuiDockNodeSettings* settings = &ctx->SettingsNodes[n];
|
||||
const char* selected_tab_name = NULL;
|
||||
if (settings->SelectedTabID)
|
||||
{
|
||||
if (ImGuiWindow* window = FindWindowByID(settings->SelectedTabID))
|
||||
selected_tab_name = window->Name;
|
||||
else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedTabID))
|
||||
selected_tab_name = window_settings->Name;
|
||||
}
|
||||
ImGui::BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentID, settings->SelectedTabID, selected_tab_name ? selected_tab_name : settings->SelectedTabID ? "N/A" : "");
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (g.IO.KeyCtrl && show_window_dock_info)
|
||||
{
|
||||
for (int n = 0; n < ctx->Nodes.Data.Size; n++)
|
||||
if (ImGuiDockNode* node = (ImGuiDockNode*)ctx->Nodes.Data[n].val_p)
|
||||
{
|
||||
ImGuiDockNode* root_node = DockNodeGetRootNode(node);
|
||||
if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(root_node, g.IO.MousePos))
|
||||
if (hovered_node != node)
|
||||
continue;
|
||||
char buf[64] = "";
|
||||
char* p = buf;
|
||||
ImDrawList* overlay_draw_list = GetOverlayDrawList();
|
||||
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsDocumentRoot ? " *DocRoot*" : "");
|
||||
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y);
|
||||
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Explicit: (%.0f, %.0f)\n", node->LastExplicitSize.x, node->LastExplicitSize.y);
|
||||
int depth = DockNodeGetDepth(node);
|
||||
overlay_draw_list->AddRect(node->Pos + ImVec2(3,3) * (float)depth, node->Pos + node->Size - ImVec2(3,3) * (float)depth, IM_COL32(200, 100, 100, 255));
|
||||
ImVec2 pos = node->Pos + ImVec2(3,3) * (float)depth;
|
||||
overlay_draw_list->AddRectFilled(pos - ImVec2(1, 1), pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
|
||||
overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf);
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Internal state"))
|
||||
{
|
||||
const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
|
||||
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredWindowUnderMovingWindow: '%s'", g.HoveredWindowUnderMovingWindow ? g.HoveredWindowUnderMovingWindow->Name : "NULL");
|
||||
ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|
||||
ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
|
||||
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
||||
@ -9094,7 +9402,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
|
||||
if (g.IO.KeyCtrl && show_window_begin_order)
|
||||
{
|
||||
for (int n = 0; n < g.Windows.Size; n++)
|
||||
|
Loading…
Reference in New Issue
Block a user