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

Table Multi Select - Column Only #8364

Open
hippyau opened this issue Jan 31, 2025 · 3 comments
Open

Table Multi Select - Column Only #8364

hippyau opened this issue Jan 31, 2025 · 3 comments

Comments

@hippyau
Copy link

hippyau commented Jan 31, 2025

Version/Branch of Dear ImGui:

1.91.7 docking

Back-ends:

imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp

Compiler, OS:

Linux, GCC-13

Full config/build information:

Dear ImGui 1.91.7 (19170)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=202002
define: __linux__
define: __GNUC__=13
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000481
 NavEnableKeyboard
 DockingEnable
 ViewportsEnable
io.ConfigViewportsNoDecoration
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigWindowsMoveFromTitleBarOnly
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 12 fonts, Flags: 0x00000000, TexSize: 4096,16384
io.DisplaySize: 1920.00,1011.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 16.00,16.00
style.WindowBorderSize: 6.00
style.FramePadding: 4.00,4.00
style.FrameRounding: 4.00
style.FrameBorderSize: 1.00
style.ItemSpacing: 6.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

My Issue/Question:

I have a table with many columns. In this table the columns will represent values all of the same time, for example all values within one column are integers, or strings, whatever... but all values in each column are the same type. (in this example, all columns are integers)

Image

Now, I want to multi-select cells only within a single column of the table, so I can set all the selected cells to the same value, like this:

Image

This looks like it's working, but I can not 'box select' with mouse around the values I want, I can only use the CTRL + SHIFT and click?

I am not sure why it's not working, because I think it should be.

Screenshots/Video:

In this video, I am using the SHIFT + CTRL keys... Dragging only works at the end outside the table (ScopeWindow flag is used, ScopeRect does not work at all)

ImGuiMultiSelect-2025-01-31_17.07.40.mp4

Minimal, Complete and Verifiable Example code:

// Just call DrawTable() in main loop...


static const int kNumRows = 10;
static const int kNumCols = 4;
static int g_Data[kNumRows][kNumCols] = {};

void InitializeTestData()
{
    static bool initialized = false;
    if (!initialized)
    {
        for (int r = 0; r < kNumRows; r++)
            for (int c = 0; c < kNumCols; c++)
                g_Data[r][c] = (r+1)*100 + c;  // arbitrary
        initialized = true;
    }
}

void DrawTable(){
	  InitializeTestData();
  
    static ImGuiSelectionBasicStorage s_Selection;
    static int  s_ActiveColumn = -1;  // -1 => no column chosen yet

    ImGui::Begin("Table Window");
    
    ImGuiMultiSelectFlags ms_flags =
          ImGuiMultiSelectFlags_ClearOnEscape
        | ImGuiMultiSelectFlags_ClearOnClickVoid
        | ImGuiMultiSelectFlags_BoxSelect2d
        | ImGuiMultiSelectFlags_ScopeWindow
        | ImGuiMultiSelectFlags_SelectOnClickRelease;

    ImGuiTableFlags TABLE_FLAGS = ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable;
    
    ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(ms_flags, s_Selection.Size, kNumRows);
    s_Selection.ApplyRequests(ms_io);
  
    if (ImGui::BeginTable("TestTable", kNumCols, TABLE_FLAGS, ImVec2(0, -24)))
    {        
        ImGui::TableSetupColumn("Col 0");
        ImGui::TableSetupColumn("Col 1");
        ImGui::TableSetupColumn("Col 2");
        ImGui::TableSetupColumn("Col 3");
        ImGui::TableHeadersRow();
        
        for (int row = 0; row < kNumRows; row++)
        {
            ImGui::TableNextRow();

            for (int col = 0; col < kNumCols; col++)
            {
                ImGui::TableSetColumnIndex(col);
                
                int cell_value = g_Data[row][col];

                // If no active column chosen yet, any click in this column can activate it
                // If we already have active column, only that column is selectable
                bool can_select_this_column = (s_ActiveColumn == -1 || s_ActiveColumn == col);

                if (can_select_this_column)
                {
                    // next item -- row index
                    ImGui::SetNextItemSelectionUserData((ImS64)row);

                    // Is row selected?
                    bool is_selected = s_Selection.Contains((ImGuiID)row);
                    
                    char label[32];
                    snprintf(label, sizeof(label), "%d", cell_value);

                    if (ImGui::Selectable(label, is_selected, ImGuiSelectableFlags_AllowItemOverlap))
                    {   
						if (s_Selection.Size == 0)
							s_ActiveColumn = col;                     
                    }

                    // If clicked inside this column and it wasn't active before, choose it as active column
                    if (s_ActiveColumn == -1 && ImGui::IsItemActivated())
                    {
                        s_ActiveColumn = col;
                    }
                }
                else
                {
                    // Another column is already active, so we are not using a selectable                                        
                    ImGui::Text("%d", cell_value);
                }
            }
        }

        ImGui::EndTable();
    }

    // end multi-select scope
    ImGuiMultiSelectIO* ms_io_end = ImGui::EndMultiSelect();
    s_Selection.ApplyRequests(ms_io_end);
    
    // clear active column if selection is empty:
    if (s_Selection.Size == 0) 
		s_ActiveColumn = -1;

    ImGui::Text("Active Column: %d   |   Selected Rows: %d", s_ActiveColumn, s_Selection.Size);

    ImGui::End();
}
@hippyau
Copy link
Author

hippyau commented Feb 1, 2025

This is driving me insane trying to work out what is happening... :)

I can see the BeginBoxSelect() activate and deactivate, but only if started outside the table, will it actually select anything?

I have tried ImGuiMultiSelectFlags_ScopeRect which shows the BeginBoxSelect() activate and deactivate, but no selection. I have tried ImGuiMultiSelectFlags_BoxSelect1d but it makes no difference.

Image

@hippyau
Copy link
Author

hippyau commented Feb 1, 2025

OMFG... I moved the ImGui::BeginMultiSelect and ImGui::EndMultiSelect inside the BeginTable / EndTable calls...

Image

@hippyau hippyau closed this as completed Feb 1, 2025
@ocornut ocornut reopened this Feb 1, 2025
@ocornut
Copy link
Owner

ocornut commented Feb 1, 2025

I’ll reopen this for now to see if there’s a documentation issue or something to improve in the code.

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

No branches or pull requests

2 participants