Issues/help with TreeNode [SOLVED]
tingspain opened this issue · comments
Hi,
I would like to ask to the community for some help/hint with some issues I am having with the TreeNodes. I am sure I missing something conceptually, so I am sorry if my questions are too trivial.
1.- Buttons are only working for the first child node of the tree (ImGui.Selectable()
widget). As I shown in the first part of the video, the buttons of the right side of each child node only work for the first node. As you can see in the video, the buttons for Object 1 node can be triggered, but the buttons for Object 2 or Object 3 nodes can not be triggered. I don't know what I am doing wrong.
2.- I would like to know how i can detect/handle when a click is made outside the Tree to clean the selection. I have tried ImGui.IsItemClicked()
with the Window (ImGui.Begin()
), with the Child Window (ImGui.BeginChild()
) and Child Window Frame (ImGui.BeginChildFrame()
) widgets but none of them worked. In the second part of the video, I show how I click outside the tree widget but not callbacks have been triggered. Any idea?
Thanks in advance for your time and help!!
VIDEO
Screen.Recording.2023-03-20.at.00.03.39.mov
CODE
if( ImGui.Begin("Scene") )
{
bool win = ImGui.BeginChildFrame( ImGui.GetID("scene"), new System.Numerics.Vector2(0, 0) );
// NOT WORKING
if (ImGui.IsItemClicked())
{
ConsoleLogger.Debug("Clicking in the Window");
selectedMesh = null;
}
if (win)
{
bool root = ImGui.TreeNodeEx("Scene", ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.AllowItemOverlap);
if (ImGui.IsItemClicked())
{
ConsoleLogger.Debug("Unselecting " + selectedMesh?.Name);
selectedMesh = null;
}
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
if (ImGui.SmallButton("+"))
ImGui.OpenPopup("ElementList");
if(ImGui.IsItemHovered())
ImGui.SetTooltip("Create new Element");
if (ImGui.BeginPopup("ElementList"))
{
ImGui.MenuItem("element 1");
ImGui.MenuItem("element 2");
ImGui.EndPopup();
}
ImGui.SameLine();
if (ImGui.SmallButton("S"))
{
ConsoleLogger.Warn("Opening Settings");
}
if (root)
{
foreach (SimpleMesh curMesh in myscene)
{
bool curSelector = ImGui.Selectable(curMesh.Name, curMesh == selectedMesh ? true : false, ImGuiSelectableFlags.DontClosePopups | ImGuiSelectableFlags.AllowItemOverlap);
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
bool curBttnE = ImGui.Button("E");
ImGui.SameLine();
bool curBttnD = ImGui.Button("D");
if (curSelector)
{
selectedMesh = curMesh;
ConsoleLogger.Debug("Selecting " + selectedMesh?.Name);
}
if (curBttnE)
ConsoleLogger.Debug("Show/Hide Object " + curMesh.Name);
if (curBttnD)
ConsoleLogger.Debug("Delete Object " + curMesh.Name);
}
ImGui.TreePop();
}
ImGui.EndChildFrame();
}
ImGui.End();
}
Solutions for Problem 2:
I solved the issue with problem 2 by using ImGui.IsMouseDown()
and ImGui.IsWindowHovered()
at Window level.
Here you have the code:
if( ImGui.Begin("Scene") )
{
bool win = ImGui.BeginChildFrame( ImGui.GetID("SceneFrame"), new System.Numerics.Vector2(0, 0) );
// [SOLUTION PROBLEM 2]
// Reset selection when it is clicked outside the tree widget
if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && ImGui.IsWindowHovered() )
selectedMesh = null;
if (win)
{
bool root = ImGui.TreeNodeEx("Scene", ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.AllowItemOverlap);
if (ImGui.IsItemClicked())
{
ConsoleLogger.Debug("Unselecting " + selectedMesh?.Name);
selectedMesh = null;
}
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
if (ImGui.SmallButton("+"))
ImGui.OpenPopup("ElementList");
if(ImGui.IsItemHovered())
ImGui.SetTooltip("Create new Element");
if (ImGui.BeginPopup("ElementList"))
{
ImGui.MenuItem("element 1");
ImGui.MenuItem("element 2");
ImGui.EndPopup();
}
ImGui.SameLine();
if (ImGui.SmallButton("S"))
{
ConsoleLogger.Warn("Opening Settings");
}
if (root)
{
foreach (SimpleMesh curMesh in myscene)
{
bool curSelector = ImGui.Selectable(curMesh.Name, curMesh == selectedMesh ? true : false, ImGuiSelectableFlags.DontClosePopups | ImGuiSelectableFlags.AllowItemOverlap);
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
bool curBttnE = ImGui.Button("E");
ImGui.SameLine();
bool curBttnD = ImGui.Button("D");
if (curSelector)
{
selectedMesh = curMesh;
ConsoleLogger.Debug("Selecting " + selectedMesh?.Name);
}
if (curBttnE)
ConsoleLogger.Debug("Show/Hide Object " + curMesh.Name);
if (curBttnD)
ConsoleLogger.Debug("Delete Object " + curMesh.Name);
}
ImGui.TreePop();
}
ImGui.EndChildFrame();
}
ImGui.End();
}
I managed to solve my two issues. I dont know if it is the most optimal way, but It is working fine. just in case, anyone want to achieve the same I pasted my solution.
SOLUTION
VIDEO
Screen.Recording.2023-03-21.at.00.09.16.mov
CODE
if( ImGui.Begin("Scene") )
{
bool win = ImGui.BeginChildFrame( ImGui.GetID("SceneFrame"), new System.Numerics.Vector2(0, 0) );
// [SOLUTION PROBLEM 2 AND PARTIALLY PROBLEM 1]
// Reset selection when it is clicked outside the tree widget
if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && ImGui.IsWindowHovered() && !ImGui.IsAnyItemHovered())
selectedMesh = null;
if (win)
{
bool root = ImGui.TreeNodeEx("Scene", ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.AllowItemOverlap);
if (ImGui.IsItemClicked())
{
ConsoleLogger.Debug("Unselecting " + selectedMesh?.Name);
selectedMesh = null;
}
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
if (ImGui.SmallButton("+"))
ImGui.OpenPopup("ElementList");
if(ImGui.IsItemHovered())
ImGui.SetTooltip("Create new Element");
if (ImGui.BeginPopup("ElementList"))
{
ImGui.MenuItem("element 1");
ImGui.MenuItem("element 2");
ImGui.EndPopup();
}
ImGui.SameLine();
if (ImGui.SmallButton("S"))
ConsoleLogger.Warn("Opening Settings");
if (root)
{
ImGui.Unindent(ImGui.GetTreeNodeToLabelSpacing());
foreach (SimpleMesh curMesh in myscene)
{
// [SOLUTION PROBLEM 1]
ImGui.TreePush(curMesh.Name);
bool curSelector = ImGui.Selectable(curMesh.Name, curMesh == selectedMesh ? true : false, ImGuiSelectableFlags.AllowItemOverlap );
ImGui.SameLine();
ImGui.Dummy(new System.Numerics.Vector2(ImGui.GetContentRegionAvail().X - 50, 0));
ImGui.SameLine();
if (ImGui.SmallButton("E"))
ConsoleLogger.Debug("Show/Hide Object " + curMesh.Name);
ImGui.SameLine();
if (ImGui.SmallButton("D"))
ConsoleLogger.Debug("Delete Object " + curMesh.Name);
if (curSelector)
selectedMesh = curMesh;
// [SOLUTION PROBLEM 1]
ImGui.TreePop();
}
ImGui.Indent(ImGui.GetTreeNodeToLabelSpacing());
ImGui.TreePop();
}
ImGui.EndChildFrame();
}
ImGui.End();
}