Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Weird yellow rectangle drawing for DragDrop TreeNodes contained in a child window #7069

Closed
Spyeedy opened this issue Nov 28, 2023 · 3 comments
Labels
drag drop drag and drop

Comments

@Spyeedy
Copy link

Spyeedy commented Nov 28, 2023

Version/Branch of Dear ImGui:
Version: 1.90 WIP (18992)
Branch: docking

Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_glfwcpp + imgui_impl_opengl3.cpp
Compiler: XXX (if the question is related to building or platform specific features)
Operating System: Windows

My Issue/Question:
I'm trying to create a scrollable region using a Child window (BeginChild / EndChild), and in this scrollable region a list of TreeNodes. Basically a scrolling area for a Tree list. Then, I implemented a re-ordering function using the DragDrop feature. However, with the BeginChild / EndChild surrounding my TreeNodes, the yellow rectangle for the DragDropTarget seems wonky (see first gallery).

But if I do not surround my TreeNodes code with BeginChild / EndChild, the yellow rectangle from the DragDropTarget seems working fine (see second gallery).

Screenshots/Video
First Gallery: Wonky yellow rectangle for DragDropTarget
2023-11-28-11-55-34

Second Gallery: No child window, DragDropTarget's yellow rectangle draws perfectly
2023-11-28-12-04-54

Standalone, minimal, complete and verifiable example:
Child window + TreeNodes

Open to see code
ImGui::SetNextWindowBgAlpha(1.0f);
if (ImGui::Begin("UI Layers", &showLayersWindow)) {
	const auto& layers = Zane::Rendering::GetLayers();

	ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4{0.2,0.2,0.2,1.0});
	ImGui::BeginChild("##layerList", ImVec2(-FLT_MIN, 6 * ImGui::GetTextLineHeightWithSpacing() + ImGui::GetTextLineHeight()));
	ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
	for (unsigned i = 0; i < layers.size(); i++) {
		const std::string& layerName = layers.at(i);

		ImGui::TreeNodeEx((void*)(uintptr_t)i, ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf, layerName.c_str());

		if (ImGui::BeginDragDropSource()) {
			ImGui::SetDragDropPayload("_LAYER_REORDER", &i, layerName.size());
			ImGui::SetTooltip(layerName.c_str());
			ImGui::EndDragDropSource();
		}
		if (ImGui::BeginDragDropTarget()) {
			if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_LAYER_REORDER")) {
				unsigned received_layer_id = *static_cast<unsigned*>(payload->Data);
				Zane::Rendering::MoveLayer(received_layer_id, i);
			}
			ImGui::EndDragDropTarget();
		}
	}
	ImGui::EndChild();
	ImGui::PopStyleColor();
	ImGui::Separator();

	static std::string newLayerName;
	ImGui::InputText("##addLayerName", &newLayerName);
	ImGui::SameLine();
	if (ImGui::Button("Add Layer")) {
		Zane::Rendering::AddLayer(newLayerName);
		newLayerName = "";
	}
}
ImGui::End();

No child window + TreeNodes (the difference is just removing the BeginChild & EndChild)

Open to see code
ImGui::SetNextWindowBgAlpha(1.0f);
if (ImGui::Begin("UI Layers", &showLayersWindow)) {
	const auto& layers = Zane::Rendering::GetLayers();

	ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4{0.2,0.2,0.2,1.0});
	ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
	for (unsigned i = 0; i < layers.size(); i++) {
		const std::string& layerName = layers.at(i);

		ImGui::TreeNodeEx((void*)(uintptr_t)i, ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf, layerName.c_str());

		if (ImGui::BeginDragDropSource()) {
			ImGui::SetDragDropPayload("_LAYER_REORDER", &i, layerName.size());
			ImGui::SetTooltip(layerName.c_str());
			ImGui::EndDragDropSource();
		}
		if (ImGui::BeginDragDropTarget()) {
			if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_LAYER_REORDER")) {
				unsigned received_layer_id = *static_cast<unsigned*>(payload->Data);
				Zane::Rendering::MoveLayer(received_layer_id, i);
			}
			ImGui::EndDragDropTarget();
		}
	}
	ImGui::PopStyleColor();
	ImGui::Separator();

	static std::string newLayerName;
	ImGui::InputText("##addLayerName", &newLayerName);
	ImGui::SameLine();
	if (ImGui::Button("Add Layer")) {
		Zane::Rendering::AddLayer(newLayerName);
		newLayerName = "";
	}
}
ImGui::End();
@GamingMinds-DanielC
Copy link
Contributor

GamingMinds-DanielC commented Nov 28, 2023

Looks like the rectangles are clipped by the draw list of your child window due to no or too little inner padding. You could push an expanded clip rect to the window draw list, but I wouldn't recommend it for the entire child as that would also expand the clipping for the items themselves, so you need to adjust it for the rectangle only.

What you can try:
Between ImGui::BeginDragDropSource() and ImGui::EndDragDropTarget() should be the best place to minimize additional draw calls because of clipping changes since you should get there at most once.

if (ImGui::BeginDragDropTarget())
{
	// code untested, but should do the trick
	ImDrawList* drawList = ImGui::GetWindowDrawList();
	drawList->PushClipRectFullScreen();

	if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_LAYER_REORDER"))
	{
		// ...
	}

	drawList->PopClipRect();
	ImGui::EndDragDropTarget();
}

This might still look strange if you have a scrollable child and highlight a partially scrolled out item. But instead of pushing a fullscreen clip rect, you could retrieve the current one and expand it just enough that highlights for fully visible items are just barely not clipped.

Alternatively (if you don't mind the additional space), you could use ImGuiWindowFlags_AlwaysUseWindowPadding for your child window, maybe adjust the window padding itself accordingly.

@ocornut ocornut added the drag drop drag and drop label Nov 28, 2023
@ocornut
Copy link
Owner

ocornut commented Nov 28, 2023

At first, try to update because we reworked this drawing code in 18993 and then again very recently (#7049).

@Spyeedy
Copy link
Author

Spyeedy commented Nov 30, 2023

I pulled the latest files from the docking branch and copied that into my project, 1.90.1 19001. This bug is gone! Thank you so much!

@Spyeedy Spyeedy closed this as completed Nov 30, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
drag drop drag and drop
Projects
None yet
Development

No branches or pull requests

3 participants