mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Docking: Internal: Added helper for automation to process docking at the mouse level.
This commit is contained in:
		
							
								
								
									
										45
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -10896,11 +10896,11 @@ namespace ImGui | ||||
|     static void             DockNodeUpdateVisibleFlag(ImGuiDockNode* node); | ||||
|     static void             DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* 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 void             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 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 bool             DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking); | ||||
|     static bool             DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking, ImVec2* test_mouse_pos); | ||||
|     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              DockNodeGetTabOrder(ImGuiWindow* window); | ||||
| @@ -11439,6 +11439,25 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) | ||||
|     MarkIniSettingsDirty(); | ||||
| } | ||||
|  | ||||
| // This is mostly used for automation. | ||||
| bool ImGui::DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos) | ||||
| { | ||||
|     if (split_outer) | ||||
|     { | ||||
|         IM_ASSERT(0); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ImGuiDockPreviewData split_data; | ||||
|         DockNodePreviewDockCalc(target, target_node, payload, &split_data, false, split_outer); | ||||
|         if (split_data.DropRectsDraw[split_dir+1].IsInverted()) | ||||
|             return false; | ||||
|         *out_pos = split_data.DropRectsDraw[split_dir+1].GetCenter(); | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // Docking: ImGuiDockNode | ||||
| //----------------------------------------------------------------------------- | ||||
| @@ -12408,7 +12427,7 @@ void ImGui::DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& po | ||||
| } | ||||
|  | ||||
| // Retrieve the drop rectangles for a given direction or for the center + perform hit testing. | ||||
| bool ImGui::DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& out_r, bool outer_docking) | ||||
| bool ImGui::DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_r, bool outer_docking, ImVec2* test_mouse_pos) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
| @@ -12440,12 +12459,15 @@ bool ImGui::DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& ou | ||||
|     else if (dir == ImGuiDir_Left)  { out_r = ImRect(c.x - off.x - hs_h, c.y - hs_w, c.x - off.x + hs_h, c.y + hs_w); } | ||||
|     else if (dir == ImGuiDir_Right) { out_r = ImRect(c.x + off.x - hs_h, c.y - hs_w, c.x + off.x + hs_h, c.y + hs_w); } | ||||
|  | ||||
|     if (test_mouse_pos == NULL) | ||||
|         return false; | ||||
|  | ||||
|     ImRect hit_r = out_r; | ||||
|     if (!outer_docking) | ||||
|     { | ||||
|         // Custom hit testing for the 5-way selection, designed to reduce flickering when moving diagonally between sides | ||||
|         hit_r.Expand(ImFloor(hs_w * 0.30f)); | ||||
|         ImVec2 mouse_delta = (g.IO.MousePos - c); | ||||
|         ImVec2 mouse_delta = (*test_mouse_pos - c); | ||||
|         float mouse_delta_len2 = ImLengthSqr(mouse_delta); | ||||
|         float r_threshold_center = hs_w * 1.4f; | ||||
|         float r_threshold_sides = hs_w * (1.4f + 1.2f); | ||||
| @@ -12454,14 +12476,13 @@ bool ImGui::DockNodeCalcDropRects(const ImRect& parent, ImGuiDir dir, ImRect& ou | ||||
|         if (mouse_delta_len2 < r_threshold_sides * r_threshold_sides) | ||||
|             return (dir == ImGetDirQuadrantFromDelta(mouse_delta.x, mouse_delta.y)); | ||||
|     } | ||||
|     return hit_r.Contains(g.IO.MousePos); | ||||
|     return hit_r.Contains(*test_mouse_pos); | ||||
| } | ||||
|  | ||||
| // host_node may be NULL if the window doesn't have a DockNode already. | ||||
| static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, ImGuiDockPreviewData* data, bool is_explicit_target, bool is_outer_docking) | ||||
| static void ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, ImGuiDockPreviewData* data, bool is_explicit_target, bool is_outer_docking) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(g.CurrentWindow == host_window);   // Because we rely on font size to calculate tab sizes | ||||
|  | ||||
|     // There is an edge case when docking into a dockspace which only has inactive nodes. | ||||
|     // In this case DockNodeTreeFindNodeByPos() will have selected a leaf node which is inactive.  | ||||
| @@ -12503,7 +12524,7 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo | ||||
|                 continue; | ||||
|             if (dir != ImGuiDir_None && !data->IsSidesAvailable) | ||||
|                 continue; | ||||
|             if (DockNodeCalcDropRects(data->FutureNode.Rect(), (ImGuiDir)dir, data->DropRectsDraw[dir+1], is_outer_docking)) | ||||
|             if (DockNodeCalcDropRectsAndTestMousePos(data->FutureNode.Rect(), (ImGuiDir)dir, data->DropRectsDraw[dir+1], is_outer_docking, &g.IO.MousePos)) | ||||
|             { | ||||
|                 data->SplitDir = (ImGuiDir)dir; | ||||
|                 data->IsSplitDirExplicit = true; | ||||
| @@ -12531,13 +12552,12 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo | ||||
|         data->FutureNode.Size = size_new; | ||||
|         data->SplitRatio = (split_dir == ImGuiDir_Right || split_dir == ImGuiDir_Down) ? (1.0f - split_ratio) : (split_ratio); | ||||
|     } | ||||
|  | ||||
|     return data->IsSplitDirExplicit; | ||||
| } | ||||
|  | ||||
| static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, const ImGuiDockPreviewData* data) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(g.CurrentWindow == host_window);   // Because we rely on font size to calculate tab sizes | ||||
|  | ||||
|     // With this option, we only display the preview on the target viewport, and the payload viewport is made transparent. | ||||
|     // To compensate for the single layer obstructed by the payload, we'll increase the alpha of the preview nodes. | ||||
| @@ -13684,8 +13704,11 @@ void ImGui::BeginAsDockableDragDropTarget(ImGuiWindow* window) | ||||
|             ImGuiDockPreviewData* split_data = &split_inner; | ||||
|             if (node && (node->ParentNode || node->IsCentralNode())) | ||||
|                 if (ImGuiDockNode* root_node = DockNodeGetRootNode(node)) | ||||
|                     if (DockNodePreviewDockCalc(window, root_node, payload_window, &split_outer, is_explicit_target, true)) | ||||
|                 { | ||||
|                     DockNodePreviewDockCalc(window, root_node, payload_window, &split_outer, is_explicit_target, true); | ||||
|                     if (split_outer.IsSplitDirExplicit) | ||||
|                         split_data = &split_outer; | ||||
|                 } | ||||
|             DockNodePreviewDockCalc(window, node, payload_window, &split_inner, is_explicit_target, false); | ||||
|             if (split_data == &split_outer) | ||||
|                 split_inner.IsDropAllowed = false; | ||||
|   | ||||
| @@ -1678,6 +1678,7 @@ namespace ImGui | ||||
|     IMGUI_API void          DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer); | ||||
|     IMGUI_API void          DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window); | ||||
|     IMGUI_API void          DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node); | ||||
|     IMGUI_API bool          DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos); | ||||
|     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          BeginAsDockableDragDropSource(ImGuiWindow* window); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user