mirror of
https://github.com/Drezil/imgui.git
synced 2025-01-19 03:16:35 +00:00
Docking: Added undocking of whole dock node by dragging from the Collapse button. Super useful and works great!
This commit is contained in:
parent
82978fc88f
commit
e647f89c33
85
imgui.cpp
85
imgui.cpp
@ -5438,7 +5438,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
|
|
||||||
// Collapse button
|
// Collapse button
|
||||||
if (!(flags & ImGuiWindowFlags_NoCollapse))
|
if (!(flags & ImGuiWindowFlags_NoCollapse))
|
||||||
if (CollapseButton(window->GetID("#COLLAPSE"), window->Pos))
|
if (CollapseButton(window->GetID("#COLLAPSE"), window->Pos, NULL))
|
||||||
window->WantCollapseToggle = true; // Defer collapsing to next frame as we are too far in the Begin() function
|
window->WantCollapseToggle = true; // Defer collapsing to next frame as we are too far in the Begin() function
|
||||||
|
|
||||||
// Close button
|
// Close button
|
||||||
@ -9537,7 +9537,6 @@ void ImGui::EndDragDropTarget()
|
|||||||
// B- inconsistent clipping/border 1-pixel issue (#2)
|
// B- inconsistent clipping/border 1-pixel issue (#2)
|
||||||
// B- fix/disable auto-resize grip on split host nodes (~#2)
|
// B- fix/disable auto-resize grip on split host nodes (~#2)
|
||||||
// B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4)
|
// B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4)
|
||||||
// B- drag from collapse button should drag entire dock node
|
|
||||||
// B- implicit, invisible per-viewport dockspace to dock to
|
// B- implicit, invisible per-viewport dockspace to dock to
|
||||||
// B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.)
|
// B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.)
|
||||||
// B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar()
|
// B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar()
|
||||||
@ -9570,13 +9569,14 @@ struct ImGuiDockRequest
|
|||||||
ImGuiDir DockSplitDir;
|
ImGuiDir DockSplitDir;
|
||||||
float DockSplitRatio;
|
float DockSplitRatio;
|
||||||
bool DockSplitOuter;
|
bool DockSplitOuter;
|
||||||
ImGuiWindow* UndockTarget;
|
ImGuiWindow* UndockTargetWindow;
|
||||||
|
ImGuiDockNode* UndockTargetNode;
|
||||||
|
|
||||||
ImGuiDockRequest()
|
ImGuiDockRequest()
|
||||||
{
|
{
|
||||||
Type = ImGuiDockRequestType_None;
|
Type = ImGuiDockRequestType_None;
|
||||||
DockTargetWindow = DockPayload = UndockTarget = NULL;
|
DockTargetWindow = DockPayload = UndockTargetWindow = NULL;
|
||||||
DockTargetNode = NULL;
|
DockTargetNode = UndockTargetNode = NULL;
|
||||||
DockSplitDir = ImGuiDir_None;
|
DockSplitDir = ImGuiDir_None;
|
||||||
DockSplitRatio = 0.5f;
|
DockSplitRatio = 0.5f;
|
||||||
DockSplitOuter = false;
|
DockSplitOuter = false;
|
||||||
@ -9636,7 +9636,8 @@ namespace ImGui
|
|||||||
static void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
static void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
||||||
static void DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
static void DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||||
static void DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req);
|
static void DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req);
|
||||||
static void DockContextProcessUndock(ImGuiContext* ctx, ImGuiWindow* window);
|
static void DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
|
||||||
|
static void DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||||
static void DockContextGcUnusedSettingsNodes(ImGuiContext* ctx);
|
static void DockContextGcUnusedSettingsNodes(ImGuiContext* ctx);
|
||||||
static void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_references); // Set root_id==0 to clear all
|
static void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_references); // Set root_id==0 to clear all
|
||||||
static void DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count);
|
static void DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count);
|
||||||
@ -9653,13 +9654,13 @@ namespace ImGui
|
|||||||
static void DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node);
|
static void DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node);
|
||||||
static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window);
|
static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window);
|
||||||
static void DockNodeUpdateVisibleFlag(ImGuiDockNode* node);
|
static void DockNodeUpdateVisibleFlag(ImGuiDockNode* node);
|
||||||
|
static void DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window);
|
||||||
static bool DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window);
|
static bool DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window);
|
||||||
static bool DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking);
|
static bool DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking);
|
||||||
static void DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data);
|
static void DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data);
|
||||||
static ImRect DockNodeCalcTabBarRect(const ImGuiDockNode* node);
|
static ImRect DockNodeCalcTabBarRect(const ImGuiDockNode* node);
|
||||||
static void DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired);
|
static void DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired);
|
||||||
static bool DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking);
|
static bool DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking);
|
||||||
static ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; }
|
|
||||||
static const char* DockNodeGetHostWindowTitle(ImGuiDockNode* node, char* buf, int buf_size) { ImFormatString(buf, buf_size, "##DockNode_%02X", node->ID); return buf; }
|
static const char* DockNodeGetHostWindowTitle(ImGuiDockNode* node, char* buf, int buf_size) { ImFormatString(buf, buf_size, "##DockNode_%02X", node->ID); return buf; }
|
||||||
static int DockNodeGetDepth(const ImGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; }
|
static int DockNodeGetDepth(const ImGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; }
|
||||||
static int DockNodeGetTabOrder(ImGuiWindow* window);
|
static int DockNodeGetTabOrder(ImGuiWindow* window);
|
||||||
@ -9766,8 +9767,13 @@ void ImGui::DockContextNewFrameUpdateUndocking(ImGuiContext* ctx)
|
|||||||
|
|
||||||
// Process Undocking requests (we need to process them _before_ the UpdateMouseMovingWindow call in NewFrame)
|
// Process Undocking requests (we need to process them _before_ the UpdateMouseMovingWindow call in NewFrame)
|
||||||
for (int n = 0; n < dc->Requests.Size; n++)
|
for (int n = 0; n < dc->Requests.Size; n++)
|
||||||
if (dc->Requests[n].Type == ImGuiDockRequestType_Undock)
|
{
|
||||||
DockContextProcessUndock(ctx, dc->Requests[n].UndockTarget);
|
ImGuiDockRequest* req = &dc->Requests[n];
|
||||||
|
if (req->Type == ImGuiDockRequestType_Undock && req->UndockTargetWindow)
|
||||||
|
DockContextProcessUndockWindow(ctx, req->UndockTargetWindow);
|
||||||
|
else if (req->Type == ImGuiDockRequestType_Undock && req->UndockTargetNode)
|
||||||
|
DockContextProcessUndockNode(ctx, req->UndockTargetNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docking context update function, called by NewFrame()
|
// Docking context update function, called by NewFrame()
|
||||||
@ -9912,7 +9918,7 @@ void ImGui::DockBuilderRemoveNodeDockedWindows(ImGuiContext* ctx, ImGuiID root_i
|
|||||||
if (want_removal)
|
if (want_removal)
|
||||||
{
|
{
|
||||||
ImGuiID backup_dock_id = window->DockId;
|
ImGuiID backup_dock_id = window->DockId;
|
||||||
DockContextProcessUndock(ctx, window);
|
DockContextProcessUndockWindow(ctx, window);
|
||||||
if (!clear_persistent_docking_references)
|
if (!clear_persistent_docking_references)
|
||||||
window->DockId = backup_dock_id;
|
window->DockId = backup_dock_id;
|
||||||
}
|
}
|
||||||
@ -10023,11 +10029,19 @@ void ImGui::DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDo
|
|||||||
ctx->DockContext->Requests.push_back(req);
|
ctx->DockContext->Requests.push_back(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::DockContextQueueUndock(ImGuiContext* ctx, ImGuiWindow* window)
|
void ImGui::DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiDockRequest req;
|
ImGuiDockRequest req;
|
||||||
req.Type = ImGuiDockRequestType_Undock;
|
req.Type = ImGuiDockRequestType_Undock;
|
||||||
req.UndockTarget = window;
|
req.UndockTargetWindow = window;
|
||||||
|
ctx->DockContext->Requests.push_back(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node)
|
||||||
|
{
|
||||||
|
ImGuiDockRequest req;
|
||||||
|
req.Type = ImGuiDockRequestType_Undock;
|
||||||
|
req.UndockTargetNode = node;
|
||||||
ctx->DockContext->Requests.push_back(req);
|
ctx->DockContext->Requests.push_back(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10118,7 +10132,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
|
|||||||
if (payload_node != NULL)
|
if (payload_node != NULL)
|
||||||
{
|
{
|
||||||
// Transfer full payload node (with 1+ child windows or child nodes)
|
// Transfer full payload node (with 1+ child windows or child nodes)
|
||||||
// FIXME-DOCK: Transition persistent DockId for all non-active windows?
|
// FIXME-DOCK: Transition persistent DockId for all non-active windows
|
||||||
if (payload_node->IsSplitNode())
|
if (payload_node->IsSplitNode())
|
||||||
{
|
{
|
||||||
if (target_node->Windows.Size > 0)
|
if (target_node->Windows.Size > 0)
|
||||||
@ -10157,7 +10171,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
|
|||||||
target_node->TabBar->NextSelectedTabId = next_selected_id;
|
target_node->TabBar->NextSelectedTabId = next_selected_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::DockContextProcessUndock(ImGuiContext* ctx, ImGuiWindow* window)
|
void ImGui::DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
if (window->DockNode)
|
if (window->DockNode)
|
||||||
@ -10169,6 +10183,22 @@ void ImGui::DockContextProcessUndock(ImGuiContext* ctx, ImGuiWindow* window)
|
|||||||
window->DockTabIsVisible = false;
|
window->DockTabIsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract a node out by creating a new one.
|
||||||
|
// In the case of a root node, a node will have to stay in place, otherwise the node will be hidden (and GC-ed later)
|
||||||
|
// (we could handle both cases differently with little benefit)
|
||||||
|
void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node)
|
||||||
|
{
|
||||||
|
// FIXME-DOCK: Transition persistent DockId for all non-active windows
|
||||||
|
(void)ctx;
|
||||||
|
IM_ASSERT(!node->IsSplitNode());
|
||||||
|
IM_ASSERT(node->Windows.Size >= 1);
|
||||||
|
ImGuiDockNode* new_node = DockContextAddNode(ctx, (ImGuiID)-1);
|
||||||
|
DockNodeMoveWindows(new_node, node);
|
||||||
|
for (int n = 0; n < new_node->Windows.Size; n++)
|
||||||
|
UpdateWindowParentAndRootLinks(new_node->Windows[n], new_node->Windows[n]->Flags, NULL);
|
||||||
|
new_node->WantMouseMove = true;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Docking: ImGuiDockNode
|
// Docking: ImGuiDockNode
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -10188,7 +10218,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
|
|||||||
SelectedTabID = 0;
|
SelectedTabID = 0;
|
||||||
WantCloseTabID = 0;
|
WantCloseTabID = 0;
|
||||||
IsVisible = true;
|
IsVisible = true;
|
||||||
InitFromFirstWindow = IsExplicitRoot = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = false;
|
InitFromFirstWindow = IsExplicitRoot = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiDockNode::~ImGuiDockNode()
|
ImGuiDockNode::~ImGuiDockNode()
|
||||||
@ -10447,6 +10477,16 @@ static void ImGui::DockNodeUpdateVisibleFlag(ImGuiDockNode* node)
|
|||||||
node->IsVisible = is_visible;
|
node->IsVisible = is_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGui::DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(node->WantMouseMove == true);
|
||||||
|
ImVec2 backup_active_click_offset = g.ActiveIdClickOffset;
|
||||||
|
StartMouseMovingWindow(window);
|
||||||
|
node->WantMouseMove = false;
|
||||||
|
g.ActiveIdClickOffset = backup_active_click_offset;
|
||||||
|
}
|
||||||
|
|
||||||
static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -10488,6 +10528,9 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
|||||||
node->WantCloseTabID = 0;
|
node->WantCloseTabID = 0;
|
||||||
node->HasCloseButton = node->HasCollapseButton = false;
|
node->HasCloseButton = node->HasCollapseButton = false;
|
||||||
node->LastFrameActive = g.FrameCount;
|
node->LastFrameActive = g.FrameCount;
|
||||||
|
|
||||||
|
if (node->WantMouseMove)
|
||||||
|
DockNodeStartMouseMovingWindow(node, node->Windows[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10553,6 +10596,8 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
|||||||
node->HostWindow = host_window = node->ParentNode->HostWindow;
|
node->HostWindow = host_window = node->ParentNode->HostWindow;
|
||||||
}
|
}
|
||||||
node->InitFromFirstWindow = false;
|
node->InitFromFirstWindow = false;
|
||||||
|
if (node->WantMouseMove && node->HostWindow)
|
||||||
|
DockNodeStartMouseMovingWindow(node, node->HostWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update active node (the one whose title bar is highlight) within a node tree
|
// Update active node (the one whose title bar is highlight) within a node tree
|
||||||
@ -10681,7 +10726,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
|
|||||||
host_window->DrawList->AddLine(title_bar_rect.GetBL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.WindowBorderSize);
|
host_window->DrawList->AddLine(title_bar_rect.GetBL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.WindowBorderSize);
|
||||||
|
|
||||||
// Collapse button
|
// Collapse button
|
||||||
if (CollapseButton(host_window->GetID("#COLLAPSE"), title_bar_rect.Min))
|
if (CollapseButton(host_window->GetID("#COLLAPSE"), title_bar_rect.Min, node))
|
||||||
OpenPopup("#TabListMenu");
|
OpenPopup("#TabListMenu");
|
||||||
if (IsItemActive())
|
if (IsItemActive())
|
||||||
focus_tab_id = tab_bar->SelectedTabId;
|
focus_tab_id = tab_bar->SelectedTabId;
|
||||||
@ -11524,7 +11569,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
|||||||
g.NextWindowData.PosUndock = false;
|
g.NextWindowData.PosUndock = false;
|
||||||
if (want_undock)
|
if (want_undock)
|
||||||
{
|
{
|
||||||
DockContextProcessUndock(ctx, window);
|
DockContextProcessUndockWindow(ctx, window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11538,7 +11583,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
|||||||
|
|
||||||
if (dock_node->IsSplitNode())
|
if (dock_node->IsSplitNode())
|
||||||
{
|
{
|
||||||
DockContextProcessUndock(ctx, window);
|
DockContextProcessUndockWindow(ctx, window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11560,7 +11605,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
|||||||
ImGuiDockNode* root_node = DockNodeGetRootNode(dock_node);
|
ImGuiDockNode* root_node = DockNodeGetRootNode(dock_node);
|
||||||
if (root_node->LastFrameAlive < g.FrameCount)
|
if (root_node->LastFrameAlive < g.FrameCount)
|
||||||
{
|
{
|
||||||
DockContextProcessUndock(ctx, window);
|
DockContextProcessUndockWindow(ctx, window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -11573,7 +11618,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
|||||||
// Undock if we are submitted earlier than the host window
|
// Undock if we are submitted earlier than the host window
|
||||||
if (dock_node->HostWindow && window->BeginOrderWithinContext < dock_node->HostWindow->BeginOrderWithinContext)
|
if (dock_node->HostWindow && window->BeginOrderWithinContext < dock_node->HostWindow->BeginOrderWithinContext)
|
||||||
{
|
{
|
||||||
DockContextProcessUndock(ctx, window);
|
DockContextProcessUndockWindow(ctx, window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,6 +769,7 @@ struct ImGuiDockNode
|
|||||||
bool HasCollapseButton :1;
|
bool HasCollapseButton :1;
|
||||||
bool WantCloseAll :1; // Set when closing all tabs at once.
|
bool WantCloseAll :1; // Set when closing all tabs at once.
|
||||||
bool WantLockSizeOnce :1;
|
bool WantLockSizeOnce :1;
|
||||||
|
bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created hode window
|
||||||
|
|
||||||
ImGuiDockNode(ImGuiID id);
|
ImGuiDockNode(ImGuiID id);
|
||||||
~ImGuiDockNode();
|
~ImGuiDockNode();
|
||||||
@ -1468,7 +1469,9 @@ namespace ImGui
|
|||||||
IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx);
|
IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx);
|
||||||
IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx);
|
IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx);
|
||||||
IMGUI_API void DockContextEndFrame(ImGuiContext* ctx);
|
IMGUI_API void DockContextEndFrame(ImGuiContext* ctx);
|
||||||
IMGUI_API void DockContextQueueUndock(ImGuiContext* ctx, ImGuiWindow* window);
|
IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
|
||||||
|
IMGUI_API void DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||||
|
inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; }
|
||||||
IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open);
|
IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open);
|
||||||
IMGUI_API void BeginAsDockableDragDropSource(ImGuiWindow* window);
|
IMGUI_API void BeginAsDockableDragDropSource(ImGuiWindow* window);
|
||||||
IMGUI_API void BeginAsDockableDragDropTarget(ImGuiWindow* window);
|
IMGUI_API void BeginAsDockableDragDropTarget(ImGuiWindow* window);
|
||||||
@ -1531,7 +1534,7 @@ namespace ImGui
|
|||||||
// Widgets
|
// Widgets
|
||||||
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
|
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
|
||||||
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
|
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
|
||||||
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
|
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node);
|
||||||
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
|
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
|
||||||
IMGUI_API void Scrollbar(ImGuiLayoutType direction);
|
IMGUI_API void Scrollbar(ImGuiLayoutType direction);
|
||||||
IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
|
IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
|
||||||
|
@ -669,7 +669,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius)
|
|||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@ -679,20 +679,34 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
|||||||
bool hovered, held;
|
bool hovered, held;
|
||||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None);
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None);
|
||||||
|
|
||||||
bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed);
|
//bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed);
|
||||||
ImVec2 off = is_dock_menu ? ImVec2((float)(int)(-g.Style.ItemInnerSpacing.x * 0.5f) + 0.5f, 0.0f) : ImVec2(0.0f, 0.0f);
|
ImVec2 off = dock_node ? ImVec2((float)(int)(-g.Style.ItemInnerSpacing.x * 0.5f) + 0.5f, 0.0f) : ImVec2(0.0f, 0.0f);
|
||||||
ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||||
if (hovered || held)
|
if (hovered || held)
|
||||||
window->DrawList->AddCircleFilled(bb.GetCenter() + off + ImVec2(0,-0.5f), g.FontSize * 0.5f + 1.0f, col, 9);
|
window->DrawList->AddCircleFilled(bb.GetCenter() + off + ImVec2(0,-0.5f), g.FontSize * 0.5f + 1.0f, col, 9);
|
||||||
|
|
||||||
if (is_dock_menu)
|
if (dock_node)
|
||||||
RenderArrowDockMenu(window->DrawList, bb.Min + g.Style.FramePadding, g.FontSize, GetColorU32(ImGuiCol_Text));
|
RenderArrowDockMenu(window->DrawList, bb.Min + g.Style.FramePadding, g.FontSize, GetColorU32(ImGuiCol_Text));
|
||||||
else
|
else
|
||||||
RenderArrow(bb.Min + g.Style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
RenderArrow(bb.Min + g.Style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
||||||
|
|
||||||
// Switch to moving the window after mouse is moved beyond the initial drag threshold
|
// Switch to moving the window after mouse is moved beyond the initial drag threshold
|
||||||
if (IsItemActive() && IsMouseDragging())
|
if (IsItemActive() && IsMouseDragging(0))
|
||||||
StartMouseMovingWindow(window);
|
{
|
||||||
|
if (dock_node != NULL && DockNodeGetRootNode(dock_node)->OnlyNodeWithWindows != dock_node)
|
||||||
|
{
|
||||||
|
float threshold_base = g.FontSize;
|
||||||
|
float threshold_x = (threshold_base * 2.2f);
|
||||||
|
float threshold_y = (threshold_base * 1.5f);
|
||||||
|
IM_ASSERT(window->DockNodeAsHost != NULL);
|
||||||
|
if (g.IO.MouseDragMaxDistanceAbs[0].x > threshold_x || g.IO.MouseDragMaxDistanceAbs[0].y > threshold_y)
|
||||||
|
DockContextQueueUndockNode(&g, dock_node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartMouseMovingWindow(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
@ -6456,7 +6470,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
// Undock
|
// Undock
|
||||||
if (undocking_tab && g.ActiveId == id && IsMouseDragging())
|
if (undocking_tab && g.ActiveId == id && IsMouseDragging())
|
||||||
{
|
{
|
||||||
DockContextQueueUndock(&g, docked_window);
|
DockContextQueueUndockWindow(&g, docked_window);
|
||||||
g.MovingWindow = docked_window;
|
g.MovingWindow = docked_window;
|
||||||
g.ActiveId = g.MovingWindow->MoveId;
|
g.ActiveId = g.MovingWindow->MoveId;
|
||||||
g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min;
|
g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min;
|
||||||
|
Loading…
Reference in New Issue
Block a user