rxi / microui

A tiny immediate-mode UI library
MIT License
3.29k stars 239 forks source link

Trying to get a window container within another window #51

Closed bogez57 closed 2 years ago

bogez57 commented 2 years ago

Right now, all I'm trying to do is get a parent window container from within a child window. I thought this was accomplished through the 'mu_get_container' function but it doesn't seem to be presenting me with a valid container. The code is as follows:

if(mu_begin_window(ctx, "Parent Window", mu_rect(200, 100, 300, 400)))
    {
        if(mu_begin_window(ctx, "Child Window1", mu_rect(0, 0, 200, 200)))
        {
            mu_Container* currentWin = mu_get_container(ctx, "Child Window1");//This does not work
            mu_Container* cnt = mu_get_current_container(ctx);//This works and returns Child Window1

            if(mu_begin_window(ctx, "Child Window2", mu_rect(0, 200, 200, 200)))
            {
                mu_Container* parentWin = mu_get_container(ctx, "Child Window1");//This does not work. Returns empty container

                mu_end_window(ctx);
            };

            mu_end_window(ctx);
        };

        mu_end_window(ctx);
    };

Am I doing something wrong? When is mu_get_container suppose to be used then?

bogez57 commented 2 years ago

After some fiddling, it seems this is by design? The reason I was asking is I wanted to be able to set a window to open while within another window/container. So it seems you can only get a container if it's already within another parent window AND only if the call to open the window and the actual begin_window call are on the same stack level so to speak. So I can't do something like:

if(mu_begin_window(ctx, "Parent Window", mu_rect(200, 100, 300, 400)))
    {
        if(mu_begin_window(ctx, "Child Window", mu_rect(200, 100, 300, 400)))
        {
            if(mu_button(ctx, "Open Another Window"))
            {
                //Won't work because this mu_get_container call is done within "Child Window". You would have to move this button up a level to the parent window
                mu_Container* cnt = mu_get_container(ctx, "Another Window");
                cnt->open = 1;
            };
            mu_end_window(ctx);
        }

        //This window won't open even if above button was pressed
        if(mu_begin_window_ex(ctx, "Another Window", mu_rect(300, 100, 300, 200), MU_OPT_CLOSED))
        {
            mu_end_window(ctx);
        };

        mu_end_window(ctx);
    };
rxi commented 2 years ago

Yes, this is by design. All window references inside a window are unique within the context of that window; this makes sense in the context of having nested sub menus (eg. imagine you have many entities each with their own window, you would want all children windows spawned from these entity windows to be unique to their parent). This means for the case you described you need to defer the opening of the window to the context of when that window is processed:

if(mu_begin_window(ctx, "Parent Window", mu_rect(200, 100, 300, 400)))
    {
        int open_other_window = 0;
        if(mu_begin_window(ctx, "Child Window", mu_rect(200, 100, 300, 400)))
        {
            if(mu_button(ctx, "Open Another Window"))
            {
                open_other_window = 1;
            };
            mu_end_window(ctx);
        }

        if (open_other_window) {
                mu_Container* cnt = mu_get_container(ctx, "Another Window");
                cnt->open = 1;
        }
        if(mu_begin_window_ex(ctx, "Another Window", mu_rect(300, 100, 300, 200), MU_OPT_CLOSED))
        {
            mu_end_window(ctx);
        };

        mu_end_window(ctx);
    };
bogez57 commented 2 years ago

Thank you for the explanation. I'm not very familiar with ui stuff so sometimes it's hard to see the 'why' for some of the library design. Appreciate it.