imgui-node-editor
imgui-node-editor copied to clipboard
ImGui::ColorEdit4 popups don't work inside a node
I have a node that has an ImGui::ColorEdit4 inside its body.
The number input fields work normally, but the tooltip, color picker and right click option popups don't work. They get positioned in the wrong place and have weird interactions with the mouse.
I know that in order to make the popups work, I should suspend the editor before rendering them, but these popups are handled inside the ImGui::ColorEdit4 function, and I can't call this outside the node.
Is there any way to make these popups work?
You can have bool openPopup and do something like this:
inside of the node's body
openPopup = ImGui::Button("OpenPopup");
outside of the node's body
ed::Suspend();
if(openPopup) {
ImGui::OpenPopup("picker");
}
ed::Resume();
ed::Suspend();
if(ImGui::BeginPopup("picker")) {
//...
ImGui::EndPopup();
}
ed::Resume();
The same thing has to be done for combo widgets. It starts being annoying. And for the combo popups, I don't think it works. The popup window position is weird, probably because I've done something wrong. @thedmd any idea how to bypass it?
To "fix" this properly ImGui modification is needed right now. I did it by adding 2 new ImGui hooks: ImGuiContextHookType_BeginWindow, ImGuiContextHookType_EndWindow that are called on start of ImGui::Begin and end of ImGui::End
bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
...
CallContextHooks(&g, ImGuiContextHookType_BeginWindow);
...
}
bool ImGui::End()
{
...
CallContextHooks(&g, ImGuiContextHookType_EndWindow);
...
}
and registering/unregistering them in ImGuiEx::Canvas::Begin/End
bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
{
...
auto beginWindowHook = ImGuiContextHook{};
beginWindowHook.UserData = this;
beginWindowHook.Type = ImGuiContextHookType_BeginWindow;
beginWindowHook.Callback = []( ImGuiContext * context, ImGuiContextHook * hook )
{
//ImGui::SetNextWindowViewport( ImGui::GetCurrentWindow()->Viewport->ID );
auto canvas = reinterpret_cast< Canvas * >( hook->UserData );
if ( canvas->m_SuspendCounter == 0 )
{
if ( ( context->NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos ) != 0 )
{
auto pos = canvas->FromLocal( context->NextWindowData.PosVal );
ImGui::SetNextWindowPos( pos, context->NextWindowData.PosCond, context->NextWindowData.PosPivotVal );
}
if ( context->BeginPopupStack.size() )
{
auto & popup = context->BeginPopupStack.back();
popup.OpenPopupPos = canvas->FromLocal( popup.OpenPopupPos );
popup.OpenMousePos = canvas->FromLocal( popup.OpenMousePos );
}
if ( context->OpenPopupStack.size() )
{
auto & popup = context->OpenPopupStack.back();
popup.OpenPopupPos = canvas->FromLocal( popup.OpenPopupPos );
popup.OpenMousePos = canvas->FromLocal( popup.OpenMousePos );
}
}
canvas->m_BeginWindowCursorBackup = ImGui::GetCursorScreenPos();
canvas->Suspend();
};
m_beginWindowHook = ImGui::AddContextHook( ImGui::GetCurrentContext(), &beginWindowHook );
auto endWindowHook = ImGuiContextHook{};
endWindowHook.UserData = this;
endWindowHook.Type = ImGuiContextHookType_EndWindow;
endWindowHook.Callback = []( ImGuiContext * ctx, ImGuiContextHook * hook )
{
auto canvas = reinterpret_cast< Canvas * >( hook->UserData );
canvas->Resume();
ImGui::SetCursorScreenPos( canvas->m_BeginWindowCursorBackup );
ImGui::GetCurrentWindow()->DC.IsSetPos = false;
};
m_endWindowHook = ImGui::AddContextHook( ImGui::GetCurrentContext(), &endWindowHook );
return true;
}
void ImGuiEx::Canvas::End()
{
...
m_InBeginEnd = false;
ImGui::RemoveContextHook( ImGui::GetCurrentContext(), m_beginWindowHook );
ImGui::RemoveContextHook( ImGui::GetCurrentContext(), m_endWindowHook );
}
Now tooltips and other spawned windows withing Canvas context work semi properly
I can confirm the above fixes the issue, would love to see this merged somehow
What can I say. Idea of using hooks will do the trick. I will look into that. This might solve whole bunch of issues. And if child windows will be taken into account maybe all related issues could be resolved.