Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ImGui::ColorEdit4 popups don't work inside a node #242

Open
brunopj1 opened this issue Jul 7, 2023 · 3 comments
Open

ImGui::ColorEdit4 popups don't work inside a node #242

brunopj1 opened this issue Jul 7, 2023 · 3 comments

Comments

@brunopj1
Copy link

brunopj1 commented Jul 7, 2023

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?

@SC5Shout
Copy link

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();

@SC5Shout
Copy link

SC5Shout commented Jul 19, 2023

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?

@lukaasm
Copy link

lukaasm commented Aug 17, 2023

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

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants