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

Text followed by SameLine and then SmallButton inside table cell disables SmallButton #7703

Open
leidegre opened this issue Jun 18, 2024 · 5 comments
Labels

Comments

@leidegre
Copy link

leidegre commented Jun 18, 2024

Version/Branch of Dear ImGui:

Version 1.90.4, Branch: master

Back-ends:

imgui_impl_win32.cpp + imgui_impl_dx12.cpp

Compiler, OS:

Windows 11 + MSVC 2022

Full config/build information:

Dear ImGui 1.90.4 (19040)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1937
define: _MSVC_LANG=202002
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx12
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: 1957.00,1072.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:

My Issue/Question:

The issue I'm having is that when I try to use SameLine the button is not interactable.

Please see attached video.

Screenshots/Video:

game_IZICOYOWNm.mp4

Minimal, Complete and Verifiable Example code:

I do think it's reproducible in the demo by adding a few lines to the advance table section. It's not the exact same problem but in this case the button disappears so I'm assuming there's something with the way the sizing calculation that's going wrong here. My problem is specially egregious because the button is visible but just not interactable.

// Try adding these lines 5871-5872 to the demo app
ImGui::Text("Oh no");
ImGui::SameLine();

The advanced table demo app column index 2 should look like this

if (ImGui::TableSetColumnIndex(2))
{
    ImGui::Text("Oh no");
    ImGui::SameLine();
    if (ImGui::SmallButton("Chop")) { item->Quantity += 1; }
    if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
    ImGui::SameLine();
    if (ImGui::SmallButton("Eat")) { item->Quantity -= 1; }
    if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
}

I can't see that the column is using a fixed width, and I've tried that as well. Doesn't seem to work. Any help or insight would be much appricated.

@leidegre
Copy link
Author

leidegre commented Jun 18, 2024

I could be completely wrong here and there's ofcourse something I'm doing that's wrong with the selectable row. Seems like it's eating the click or something. I can only get it to work if I get a button on a different line.

Here's the complete code for the table.

void game::show_data_explorer_debug_window(Game_State* state) {
  if (!ImGui::Begin("Data Explorer", &state->tools_.data_explorer_.show_)) {
    ImGui::End();
    return; // early out
  }

  auto table_flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg;
  auto table_outer_size = ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 8);

  static ImGuiTextFilter filter;
  
  filter.Draw();
  // ImGui::SameLine();
  if (ImGui::Button("Clear")) {
    filter.Clear();
  }

  // todo: scratch allocator
  List<int> filtered = { .allocator_ = state->frame_allocator_ };
  defer (filtered.destroy());
  for (int i = 0; i < (int)Asset_Table_Size; i += 1) {
    const Asset& asset = Asset_Table[i];
    if (filter.PassFilter(asset.path_.begin(), asset.path_.end())) {
      filtered.add(i);
    }
  }
  
  if (ImGui::BeginTable("Assets Table", 2, table_flags, table_outer_size)) {
    ImGui::TableSetupScrollFreeze(0, 1);
    ImGui::TableSetupColumn("Path", ImGuiTableColumnFlags_None, 0, 0);
    ImGui::TableSetupColumn("Mem", ImGuiTableColumnFlags_WidthFixed, 100, 1);
    ImGui::TableHeadersRow();

    ImGuiListClipper clipper;
    clipper.Begin((int)filtered.size());
    while (clipper.Step())
    {
        for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++)
        {
            auto& asset = Asset_Table[filtered[row]];

            ImGui::PushID(row);
            ImGui::TableNextRow();

            ImGui::TableSetColumnIndex(0);
            
            bool is_selected = state->tools_.data_explorer_.selected_asset_ == &asset;
            if (ImGui::Selectable(asset.path_.begin(), &is_selected, ImGuiSelectableFlags_SpanAllColumns)) {
              state->tools_.data_explorer_.selected_asset_ = &asset;
            }

            // don't know if we need these, maybe it's enough to just do filename
            ImGui::TableSetColumnIndex(1);
            ImGui::Text("%zu", asset.data_.size()); // Size of this asset in memory, if it is zero then it is not loaded.
            
            // Does not work, will render button non-interactable.
            ImGui::SameLine();

            if (0 < asset.data_.size()) {
              if (ImGui::SmallButton("Reload")) { 
                // ...
              }              
            } else {
              if (ImGui::SmallButton("Load")) { 
                OR_ABORT(load_asset(&asset));
              }
            }

            ImGui::PopID();
        }
    }

    ImGui::EndTable();
  }

  ImGui::End();
}

@leidegre
Copy link
Author

leidegre commented Jun 18, 2024

Tried 1.90.8 unfortunately it didn't fix my issue.

@lukaasm
Copy link
Contributor

lukaasm commented Jun 18, 2024

use ImGui::SetNextItemAllowOverlap() before selectable

When multiple widgets fight over same interactive air-space ( selectable and button in this case ), first one that is encountered consumes action by default( selectable ). You can change this behaviour by allowing overlap on item that consumed your actions with side-effect that click action will be delayed by a frame

@leidegre
Copy link
Author

leidegre commented Jun 19, 2024

use ImGui::SetNextItemAllowOverlap() before selectable

@lukaasm Great, thanks this works 👍Do you know what makes my code special? This doesn't seem to be used in the advanced table demo.

@lukaasm
Copy link
Contributor

lukaasm commented Jun 20, 2024

Do you know what makes my code special? This doesn't seem to be used in the advanced table demo.

Because in Advanced table demo Selectable is submited with: ImGuiSelectableFlags_AllowOverlap flag which enables same behaviour as calling ImGui::SetNextItemAllowOverlap()

ImGuiSelectableFlags selectable_flags = (contents_type == CT_SelectableSpanRow) ? ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap : ImGuiSelectableFlags_None;
if (ImGui::Selectable(label, item_is_selected, selectable_flags, ImVec2(0, row_min_height)))

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

No branches or pull requests

3 participants