mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 11:39:15 +08:00
Docking: Fixed dragging/resizing from OS decoration not marking settings as dirty.
Internals: Added IMGUI_DEBUG_LOG_DOCKING, IMGUI_DEBUG_LOG_VIEWPORT macros to easily enable/disable a bunch of logging code.
This commit is contained in:
parent
efc4c0fe9d
commit
969278fc0b
54
imgui.cpp
54
imgui.cpp
@ -6108,7 +6108,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Synchronize window --> viewport in most situations
|
||||
// Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM
|
||||
if (window->Viewport->PlatformRequestMove)
|
||||
{
|
||||
window->Pos = window->Viewport->Pos;
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
else if (memcmp(&window->Viewport->Pos, &window->Pos, sizeof(window->Pos)) != 0)
|
||||
{
|
||||
viewport_rect_changed = true;
|
||||
@ -6116,7 +6119,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
}
|
||||
|
||||
if (window->Viewport->PlatformRequestResize)
|
||||
{
|
||||
window->Size = window->SizeFull = window->Viewport->Size;
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
else if (memcmp(&window->Viewport->Size, &window->Size, sizeof(window->Size)) != 0)
|
||||
{
|
||||
viewport_rect_changed = true;
|
||||
@ -6453,7 +6459,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
window->Viewport->PlatformRequestClose = false;
|
||||
g.NavWindowingToggleLayer = false; // Assume user mapped PlatformRequestClose on ALT-F4 so we disable ALT for menu toggle. False positive not an issue.
|
||||
//IMGUI_DEBUG_LOG("Window '%s' PlatformRequestClose\n", window->Name);
|
||||
IMGUI_DEBUG_LOG_VIEWPORT("Window '%s' PlatformRequestClose\n", window->Name);
|
||||
*p_open = false;
|
||||
}
|
||||
}
|
||||
@ -10259,7 +10265,7 @@ void ImGui::SetCurrentViewport(ImGuiWindow* current_window, ImGuiViewportP* view
|
||||
if (g.CurrentViewport == viewport)
|
||||
return;
|
||||
g.CurrentViewport = viewport;
|
||||
//IMGUI_DEBUG_LOG("SetCurrentViewport changed '%s' 0x%08X\n", current_window ? current_window->Name : NULL, viewport ? viewport->ID : 0);
|
||||
//IMGUI_DEBUG_LOG_VIEWPORT("SetCurrentViewport changed '%s' 0x%08X\n", current_window ? current_window->Name : NULL, viewport ? viewport->ID : 0);
|
||||
|
||||
// Notify platform layer of viewport changes
|
||||
// FIXME-DPI: This is only currently used for experimenting with handling of multiple DPI
|
||||
@ -10414,7 +10420,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
||||
g.Viewports.erase(g.Viewports.Data + n);
|
||||
|
||||
// Destroy
|
||||
//IMGUI_DEBUG_LOG("Delete Viewport %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
|
||||
IMGUI_DEBUG_LOG_VIEWPORT("Delete Viewport %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
|
||||
DestroyPlatformWindow(viewport); // In most circumstances the platform window will already be destroyed here.
|
||||
IM_ASSERT(g.PlatformIO.Viewports.contains(viewport) == false);
|
||||
IM_DELETE(viewport);
|
||||
@ -10585,7 +10591,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
|
||||
viewport->Flags = flags;
|
||||
UpdateViewportPlatformMonitor(viewport);
|
||||
g.Viewports.push_back(viewport);
|
||||
//IMGUI_DEBUG_LOG("Add Viewport %08X (%s)\n", id, window->Name);
|
||||
IMGUI_DEBUG_LOG_VIEWPORT("Add Viewport %08X (%s)\n", id, window->Name);
|
||||
|
||||
// We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport.
|
||||
// We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
|
||||
@ -10709,7 +10715,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
|
||||
if ((window->Flags & ImGuiWindowFlags_DockNodeHost) && window->Viewport->LastFrameActive < g.FrameCount && will_be_visible)
|
||||
{
|
||||
// Steal/transfer ownership
|
||||
//IMGUI_DEBUG_LOG("[%05d] Window '%s' steal Viewport %08X from Window '%s'\n", g.FrameCount, window->Name, window->Viewport->ID, window->Viewport->Window->Name);
|
||||
IMGUI_DEBUG_LOG_VIEWPORT("Window '%s' steal Viewport %08X from Window '%s'\n", window->Name, window->Viewport->ID, window->Viewport->Window->Name);
|
||||
window->Viewport->Window = window;
|
||||
window->Viewport->ID = window->ID;
|
||||
window->Viewport->LastNameHash = 0;
|
||||
@ -10773,7 +10779,7 @@ void ImGui::UpdatePlatformWindows()
|
||||
bool is_new_platform_window = (viewport->PlatformWindowCreated == false);
|
||||
if (is_new_platform_window)
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("Create Platform Window %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
|
||||
IMGUI_DEBUG_LOG_VIEWPORT("Create Platform Window %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
|
||||
g.PlatformIO.Platform_CreateWindow(viewport);
|
||||
if (g.PlatformIO.Renderer_CreateWindow != NULL)
|
||||
g.PlatformIO.Renderer_CreateWindow(viewport);
|
||||
@ -11187,7 +11193,7 @@ void ImGui::DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear
|
||||
// This function also acts as a defacto test to make sure we can rebuild from scratch without a glitch
|
||||
void ImGui::DockContextRebuild(ImGuiContext* ctx)
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("[docking] full rebuild\n");
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextRebuild()\n");
|
||||
ImGuiDockContext* dc = ctx->DockContext;
|
||||
SaveIniSettingsToMemory();
|
||||
ImGuiID root_id = 0; // Rebuild all
|
||||
@ -11284,6 +11290,7 @@ static ImGuiDockNode* ImGui::DockContextAddNode(ImGuiContext* ctx, ImGuiID id)
|
||||
id = DockContextGenNodeID(ctx);
|
||||
else
|
||||
IM_ASSERT(DockContextFindNodeByID(ctx, id) == NULL);
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextAddNode 0x%08X\n", id);
|
||||
ImGuiDockNode* node = IM_NEW(ImGuiDockNode)(id);
|
||||
ctx->DockContext->Nodes.SetVoidPtr(node->ID, node);
|
||||
return node;
|
||||
@ -11294,7 +11301,7 @@ static void ImGui::DockContextRemoveNode(ImGuiContext* ctx, ImGuiDockNode* node,
|
||||
ImGuiContext& g = *ctx;
|
||||
ImGuiDockContext* dc = ctx->DockContext;
|
||||
|
||||
//printf("[%05d] RemoveNode 0x%04X\n", node->ID);
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextRemoveNode 0x%08X\n", node->ID);
|
||||
IM_ASSERT(DockContextFindNodeByID(ctx, node->ID) == node);
|
||||
IM_ASSERT(node->ChildNodes[0] == NULL && node->ChildNodes[1] == NULL);
|
||||
IM_ASSERT(node->Windows.Size == 0);
|
||||
@ -11380,6 +11387,7 @@ static void ImGui::DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx)
|
||||
remove |= (data_root->CountChildWindows == 0);
|
||||
if (remove)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextPruneUnusedSettingsNodes: Prune 0x%08X\n", settings->ID);
|
||||
DockSettingsRemoveNodeReferences(&settings->ID, 1);
|
||||
settings->ID = 0;
|
||||
}
|
||||
@ -11488,6 +11496,10 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
|
||||
ImGuiWindow* payload_window = req->DockPayload; // Optional
|
||||
ImGuiWindow* target_window = req->DockTargetWindow;
|
||||
ImGuiDockNode* node = req->DockTargetNode;
|
||||
if (payload_window)
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextProcessDock node 0x%08X target '%s' dock window '%s', split_dir %d\n", node ? node->ID : 0, target_window ? target_window->Name : "NULL", payload_window ? payload_window->Name : "NULL", req->DockSplitDir);
|
||||
else
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockContextProcessDock node 0x%08X, split_dir %d\n", node ? node->ID : 0, req->DockSplitDir);
|
||||
|
||||
// Decide which Tab will be selected at the end of the operation
|
||||
ImGuiID next_selected_id = 0;
|
||||
@ -11726,6 +11738,7 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b
|
||||
DockNodeRemoveWindow(window->DockNode, window, 0);
|
||||
}
|
||||
IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL);
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockNodeAddWindow node 0x%08X window '%s'\n", node->ID, window->Name);
|
||||
|
||||
node->Windows.push_back(window);
|
||||
node->WantHiddenTabBarUpdate = true;
|
||||
@ -11783,6 +11796,7 @@ static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window
|
||||
//IM_ASSERT(window->RootWindow == node->HostWindow);
|
||||
//IM_ASSERT(window->LastFrameActive < g.FrameCount); // We may call this from Begin()
|
||||
IM_ASSERT(save_dock_id == 0 || save_dock_id == node->ID);
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockNodeRemoveWindow node 0x%08X window '%s'\n", node->ID, window->Name);
|
||||
|
||||
window->DockNode = NULL;
|
||||
window->DockIsActive = window->DockTabWantClose = false;
|
||||
@ -12454,12 +12468,18 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
|
||||
int tabs_unsorted_start = tab_bar->Tabs.Size;
|
||||
for (int tab_n = tab_bar->Tabs.Size - 1; tab_n >= 0 && (tab_bar->Tabs[tab_n].Flags & ImGuiTabItemFlags_Unsorted); tab_n--)
|
||||
{
|
||||
// FIXME-DOCKING: Consider only clearing the flag after the tab has been alive for a few consecutive frames, allowing late comers to not break sorting?
|
||||
tab_bar->Tabs[tab_n].Flags &= ~ImGuiTabItemFlags_Unsorted;
|
||||
tabs_unsorted_start = tab_n;
|
||||
}
|
||||
//printf("[%05d] Sorting %d new appearing tabs\n", g.FrameCount, tab_bar->Tabs.Size - tabs_unsorted_start);
|
||||
if (tab_bar->Tabs.Size > tabs_unsorted_start)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_DOCKING("In node 0x%08X: %d new appearing tabs:%s\n", node->ID, tab_bar->Tabs.Size - tabs_unsorted_start, (tab_bar->Tabs.Size > tabs_unsorted_start + 1) ? " (will sort)" : "");
|
||||
for (int tab_n = tabs_unsorted_start; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
IMGUI_DEBUG_LOG_DOCKING(" - Tab '%s' Order %d\n", tab_bar->Tabs[tab_n].Window->Name, tab_bar->Tabs[tab_n].Window->DockOrder);
|
||||
if (tab_bar->Tabs.Size > tabs_unsorted_start + 1)
|
||||
ImQsort(tab_bar->Tabs.Data + tabs_unsorted_start, tab_bar->Tabs.Size - tabs_unsorted_start, sizeof(ImGuiTabItem), TabItemComparerByDockOrder);
|
||||
}
|
||||
|
||||
// Selected newly added tabs, or persistent tab ID if the tab bar was just recreated
|
||||
if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabID) != NULL)
|
||||
@ -12985,6 +13005,7 @@ void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
|
||||
IM_ASSERT(parent_node->TabBar == NULL);
|
||||
IM_ASSERT(parent_node->Windows.Size == 0);
|
||||
}
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockNodeTreeMerge 0x%08X & 0x%08X back into parent 0x%08X\n", child_0 ? child_0->ID : 0, child_1 ? child_1->ID : 0, parent_node->ID);
|
||||
|
||||
ImVec2 backup_last_explicit_size = parent_node->SizeRef;
|
||||
DockNodeMoveChildNodes(parent_node, merge_lead_child);
|
||||
@ -13316,9 +13337,12 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags fla
|
||||
ImGuiDockNode* node = DockContextFindNodeByID(ctx, id);
|
||||
if (!node)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockSpace: dockspace node 0x%08X created\n", id);
|
||||
node = DockContextAddNode(ctx, id);
|
||||
node->LocalFlags |= ImGuiDockNodeFlags_CentralNode;
|
||||
}
|
||||
if (window_class && window_class->ClassId != node->WindowClass.ClassId)
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockSpace: dockspace node 0x%08X: setup WindowClass 0x%08X -> 0x%08X\n", id, node->WindowClass.ClassId, window_class->ClassId);
|
||||
node->SharedFlags = flags;
|
||||
node->WindowClass = window_class ? *window_class : ImGuiWindowClass();
|
||||
|
||||
@ -13352,6 +13376,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags fla
|
||||
SetNextWindowSize(node->Size);
|
||||
g.NextWindowData.PosUndock = false;
|
||||
|
||||
// FIXME-DOCKING: Why do we need a child window to host a dockspace, could we host it in the existing window?
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_DockNodeHost;
|
||||
window_flags |= ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar;
|
||||
window_flags |= ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
|
||||
@ -13611,6 +13636,7 @@ ImGuiID ImGui::DockBuilderSplitNode(ImGuiID id, ImGuiDir split_dir, float size_r
|
||||
{
|
||||
ImGuiContext* ctx = GImGui;
|
||||
IM_ASSERT(split_dir != ImGuiDir_None);
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockBuilderSplitNode node 0x%08X, split_dir %d\n", id, split_dir);
|
||||
|
||||
ImGuiDockNode* node = DockContextFindNodeByID(ctx, id);
|
||||
if (node == NULL)
|
||||
@ -13661,7 +13687,7 @@ static ImGuiDockNode* DockBuilderCopyNodeRec(ImGuiDockNode* src_node, ImGuiID ds
|
||||
dst_node->ChildNodes[child_n]->ParentNode = dst_node;
|
||||
}
|
||||
|
||||
//IMGUI_DEBUG_LOG("Fork node %08X -> %08X (%d childs)\n", src_node->ID, dst_node->ID, dst_node->IsSplitNode() ? 2 : 0);
|
||||
IMGUI_DEBUG_LOG_DOCKING("Fork node %08X -> %08X (%d childs)\n", src_node->ID, dst_node->ID, dst_node->IsSplitNode() ? 2 : 0);
|
||||
return dst_node;
|
||||
}
|
||||
|
||||
@ -13753,13 +13779,14 @@ void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_docks
|
||||
if (dst_dock_id != 0)
|
||||
{
|
||||
// Docked windows gets redocked into the new node hierarchy.
|
||||
//IMGUI_DEBUG_LOG("Remap window '%s' %08X -> %08X\n", dst_window_name, src_dock_id, dst_dock_id);
|
||||
IMGUI_DEBUG_LOG_DOCKING("Remap live window '%s' 0x%08X -> '%s' 0x%08X\n", src_window_name, src_dock_id, dst_window_name, dst_dock_id);
|
||||
DockBuilderDockWindow(dst_window_name, dst_dock_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Floating windows gets their settings transferred (regardless of whether the new window already exist or not)
|
||||
// When this is leading to a Copy and not a Move, we would get two overlapping floating windows. Could we possibly dock them together?
|
||||
IMGUI_DEBUG_LOG_DOCKING("Remap window settings '%s' -> '%s'\n", src_window_name, dst_window_name);
|
||||
DockBuilderCopyWindowSettings(src_window_name, dst_window_name);
|
||||
}
|
||||
}
|
||||
@ -13778,7 +13805,7 @@ void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_docks
|
||||
continue;
|
||||
|
||||
// Docked windows gets redocked into the new node hierarchy.
|
||||
//IMGUI_DEBUG_LOG("Remap window '%s' %08X -> %08X\n", window->Name, src_dock_id, dst_dock_id);
|
||||
IMGUI_DEBUG_LOG_DOCKING("Remap window '%s' %08X -> %08X\n", window->Name, src_dock_id, dst_dock_id);
|
||||
DockBuilderDockWindow(window->Name, dst_dock_id);
|
||||
}
|
||||
}
|
||||
@ -14047,6 +14074,7 @@ void ImGui::BeginAsDockableDragDropTarget(ImGuiWindow* window)
|
||||
static void ImGui::DockSettingsRenameNodeReferences(ImGuiID old_node_id, ImGuiID new_node_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IMGUI_DEBUG_LOG_DOCKING("DockSettingsRenameNodeReferences: from 0x%08X -> to 0x%08X\n", old_node_id, new_node_id);
|
||||
for (int window_n = 0; window_n < g.Windows.Size; window_n++)
|
||||
{
|
||||
ImGuiWindow* window = g.Windows[window_n];
|
||||
@ -14586,6 +14614,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
(flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "",
|
||||
(flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
|
||||
(flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : "");
|
||||
ImGui::BulletText("WindowClassId: 0x%08X", window->WindowClass.ClassId);
|
||||
ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, window->ScrollMax.x, window->Scroll.y, window->ScrollMax.y);
|
||||
ImGui::BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1);
|
||||
ImGui::BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems);
|
||||
@ -14897,6 +14926,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
char* p = buf;
|
||||
ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
|
||||
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : "");
|
||||
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId);
|
||||
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, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y);
|
||||
int depth = DockNodeGetDepth(node);
|
||||
|
@ -156,6 +156,10 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#ifndef IMGUI_DEBUG_LOG
|
||||
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
|
||||
#endif
|
||||
#define IMGUI_DEBUG_LOG_VIEWPORT(...) ((void)0) // Disable log
|
||||
#define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log
|
||||
//#define IMGUI_DEBUG_LOG_VIEWPORT IMGUI_DEBUG_LOG // Enable log
|
||||
//#define IMGUI_DEBUG_LOG_DOCKING IMGUI_DEBUG_LOG // Enable log
|
||||
|
||||
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
|
||||
#ifdef _MSC_VER
|
||||
|
Loading…
Reference in New Issue
Block a user