ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.16k stars 10.31k forks source link

Creating checkboxes from a list of values #7472

Closed duhnyel closed 7 months ago

duhnyel commented 7 months ago

Version/Branch of Dear ImGui:

Version 1.90.4 WIP, Branch: master

Back-ends:

imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp

Compiler, OS:

Linux + cmake(ninja + gcc)

Full config/build information:

Dear ImGui 1.90.4 WIP (19031)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201402
define: __linux__
define: __GNUC__=10
--------------------------------
io.BackendPlatformName: imgui_impl_sdl3
io.BackendRendererName: imgui_impl_sdlrenderer3
io.ConfigFlags: 0x00000003
 NavEnableKeyboard
 NavEnableGamepad
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000000E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

I'm trying to create checkboxes from an array of values but for some reason it doesn't set the value of the boolean inside the array. The checkbox just stays blank or quickly flashes checked and the value of the boolean doesn't change. What to do?

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

// here is a snippet to reproduce the issue
// as you can see it doesn't keep the checkbox checked 
bool foo[2] = {false, false};
ImGui::Begin("Hello, world!");                   
for(int i = 0; i < sizeof(foo); i++){
    ImGui::Checkbox("test", &foo[i]);
}
ImGui::End();
inobelar commented 7 months ago

@duhnyel This seems to be due to the lifetime of the variables. Apparently, you have foo existing "at frame time", that is - initialized to false , (possibly) modified during ImGui::Checkbox(), and rendered, and so on in a loop. Try to increase the lifetime of the variable: make it static, or store it outside the “main loop”:

// Static way, prefered for quick hacking
static bool foo[2] = {false, false};
ImGui::Begin("Hello, world!");                   
for(int i = 0; i < sizeof(foo); i++){
    ImGui::Checkbox("test", &foo[i]);
}
ImGui::End();
// Store-out-the-loop way
bool foo[2] = {false, false};

while(run_main_loop)
{
    // ... Inputs handling ...

    ImGui::Begin("Hello, world!");                   
    for(int i = 0; i < sizeof(foo); i++){
        ImGui::Checkbox("test", &foo[i]);
    }
    ImGui::End();

    // ... Rendering ...
}
duhnyel commented 7 months ago

That has seemed solve the problem but only partially. After moving the declaration outside the loop the top checkbox works but any others underneath, don't. I also can't make the list static for the actual implementation in my project. The code i use is this:

bool foo[4] = {false, false, false, false};
while (run_main_loop){
        ImGui::Begin("Hello, world!");
        for(int i = 0; i < sizeof(foo); i++){
             ImGui::Checkbox("test", &foo[i]);
        }
        ImGui::End();
}
inobelar commented 7 months ago

@duhnyel Its an issue with same Checkbox label (all checkboxes have "test" label/ID). You can solve it by wrapping Checkbox() call with PushID()/PopID(). You can read about ID system here.

bool foo[4] = {false, false, false, false};
while (run_main_loop)
{
    if( ImGui::Begin("Hello, world!") )
    {
        for(size_t i = 0; i < IM_ARRAYSIZE(foo); i++)
        {
            ImGui::PushID(&foo[i]);
            ImGui::Checkbox("test", &foo[i]);
            ImGui::PopID();
        }
    }
    ImGui::End();
}
ocornut commented 7 months ago

Thank you Yurii for your answers. They are both correct answers. Closing this. Good luck Alyssa with your work ahead.