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

Creating panels with unrelated data #5609

Closed
redorav opened this issue Aug 24, 2022 · 9 comments
Closed

Creating panels with unrelated data #5609

redorav opened this issue Aug 24, 2022 · 9 comments

Comments

@redorav
Copy link

redorav commented Aug 24, 2022

Version: 1.89 WIP
Branch: master
Back-ends: DX11
Operating System: Windows

My Issue/Question:

I'm trying to create a set of resizable panels to put data that is unrelated side by side. I want it to be resizable, and I want each column to be able to sort according to some criteria. I've tried the tables API as it seemed like the most appropriate but I cannot populate the data unless it's row by row, which isn't what I want because in the first column I render a tree, and in the other columns I render an actual table. See screenshot for what I currently have which is a bit of a hack as it's a table inside the column of another table. What's the best way to go about solving this? I've looked at the demo but I cannot find anything equivalent.

Screenshots/Video

image

The current code looks roughly like

ImGuiTableFlags tableFlags = 0;
tableFlags |= ImGuiTableFlags_Resizable;
tableFlags |= ImGuiTableFlags_BordersOuter;
tableFlags |= ImGuiTableFlags_BordersV;
tableFlags |= ImGuiTableFlags_ScrollY;

if (ImGui::BeginTable("##table1", 2, tableFlags))
{
  // Set up header rows
  ImGui::TableSetupColumn("Variable Groups");
  ImGui::TableHeadersRow();
  
  // Exit header row
  ImGui::TableNextRow();
  
  ImGui::TableSetColumnIndex(0);
  
  // Render the tree
  
  ImGui::TableSetColumnIndex(1);

  ImGuiTableFlags tableFlags = 0;
  tableFlags |= ImGuiTableFlags_Resizable;
  tableFlags |= ImGuiTableFlags_PadOuterX; // Because we've not enabled ImGuiTableFlags_BordersV
  tableFlags |= ImGuiTableFlags_ScrollY;

  if (ImGui::BeginTable("##UIVariableWindow", 2, tableFlags))
  {
    // Set up header rows
    ImGui::TableSetupColumn("Name");
    ImGui::TableSetupColumn("Value");
    ImGui::TableHeadersRow();
    
    // Exit header row
    ImGui::TableNextRow();
    
    // Render the data that goes into name and value
  
    foreach(name, value)
    {
	    ImGui::TableNextRow();
    
	    ImGui::TableSetColumnIndex(0);
	    ImGui::Text(name);
    
	    ImGui::TableSetColumnIndex(1);  
	    ImGui::Text(value);
    });
    
    ImGui::EndTable();
  }
  ImGui::EndTable();
}
@ocornut
Copy link
Owner

ocornut commented Aug 24, 2022

a bit of a hack as it's a table inside the column of another table

This seems perfectly fine, not sure what is the problem you are having with it?

We technically have internal helpers like SplitterBehavior() (#319) but Tables are ready to use and fine. You may also simply use the Docking branch ( https://github.com/ocornut/imgui/wiki/Docking ) and dock two windows manually.

@ocornut ocornut added the layout label Aug 24, 2022
@redorav
Copy link
Author

redorav commented Aug 24, 2022

The reason I don't like it is that there are 2 tables, one nested inside the column of the first, instead of a single table that has 3 columns, one for the tree, another for the variable title and another for the data. I've not managed to populate the first column separately to the other two columns which is what I'd really like, but make them behave in a coherent manner.

The SplitterBehavior wouldn't allow the separators to work across the two tables though would it? I could try it out see where it takes me.

I am using the docking branch so I could try that as well. Am I able to dock windows but disallow the undocking? Such that they always behave as a single window, with a separator in the middle. If that is the case then maybe that's the best option.

@thedmd
Copy link
Contributor

thedmd commented Aug 25, 2022

Disjoining rows in table columns is against what the table is actually build for, I think. : )

You may consider layout like this one. Tree and properties can then have individual scrollbars which does not interfere with each other.
With enough fiddling around splitter rendering and table border, whole thing can be made to look like a single table if that look you're after too.

  Table/List                Table
 
     │     Splitter           │
     │      Widget            │
     ↓        ↓               ↓
┌────────────┐│┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
│    Tree    ││┃ Name         ┃ Value         ┃
│            ││┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│            │││              │               │
│            │││              │               │
│            │││              │               │
│            │││              │               │
│            │││              │               │
│            │││              │               │
└────────────┘│└──────────────┴───────────────┘

For reference: Splitter

@ocornut
Copy link
Owner

ocornut commented Aug 25, 2022

The reason I don't like it is that there are 2 tables, one nested inside the column of the first, instead of a single table that has 3 columns, one for the tree, another for the variable title and another for the data.

You are repeating the initial idea but ihmo that’s not a good reason by itself. Are you bothered about an implementation detail? Or you bothered by how it affects user experience, or prevents you from achieving other things?

Since all the complicated mumbo-jumbo of clipping is performed for the horizontal axis, I imagine it may be technically achievable to twist tables into during this, but right now you aren’t stating a reason why it is a necessary development to engage on.

@redorav
Copy link
Author

redorav commented Aug 25, 2022

Yeah I'm bothered about the look and the user experience, I've never seen an application quite like that, with a table hanging off of some other panel. I've photoshopped what I'd want it to look like here.

image

@thedmd makes a very good point though that the scrollbar (which I haven't seen yet because my test app doesn't have enough elements) would affect both the tree and the variables and that's not desirable either. I don't think the single table approach is the solution to this and I think you'd both agree. I haven't had time to implement the behavior via the splitter but I really appreciate you taking the time to draw the diagram and I'll test it asap.

@ocornut
Copy link
Owner

ocornut commented Aug 25, 2022

Yeah I'm bothered about the look and the user experience, I've never seen an application quite like that, with a table hanging off of some other panel. I've photoshopped what I'd want it to look like here.

About the look and the weird header line in your first screenshot. Well maybe put a table in there so they align? In the first screenshot it looks like you put the table header in the wrong location.

Use 1 outer table with 2 columns with no decoration (only a resizing bar), and inside each column submit 1 table with the decoration and scrolling, so you'll have 3 tables in total.

(A table can perfectly be used as splitter)

@redorav
Copy link
Author

redorav commented Aug 25, 2022

Use 1 outer table with 2 columns with no decoration (only a resizing bar), and inside each column submit 1 table with the decoration and scrolling, so you'll have 3 tables in total.

(A table can perfectly be used as splitter)

Right, I hadn't thought about that approach at all, I'll give that suggestion a go too. I'm not that well versed in all the imgui tricks yet, this application is being a good learning experience for me.

@redorav
Copy link
Author

redorav commented Aug 25, 2022

I tried the last approach suggested (an invisible table with two tables inside) and I've achieved 95% success with it. I think it's probably very similar to the SplitterBehavior but I wanted to stay away from function inside _internal. This is what it's looking like now.

image

The only thing I've not been able to do is remove a small 1 pixel padding at the top between the border of the enclosing table and the tables inside. I've been trying every flag in the set of flags for the table and can't really find what I'm looking for. I have a feeling it belongs to the border of the invisible header. Is that possible? I don't see this gap in tables with a header row.

image

Any last suggestions? Sounds like I'm really close to the end result, I really appreciate the support so far. The code at this point looks like this. Both inner tables share the same flags.

ImGuiTableFlags containerTableFlags = 0;
containerTableFlags |= ImGuiTableFlags_Resizable; // Add the resizing line down the middle
containerTableFlags |= ImGuiTableFlags_BordersOuter; // Add the border
containerTableFlags |= ImGuiTableFlags_ScrollY;
containerTableFlags |= ImGuiTableFlags_NoPadOuterX;
containerTableFlags |= ImGuiTableFlags_NoPadInnerX;

if (ImGui::BeginTable("##ContainerTable", 2, containerTableFlags))
{
  // Exit header row
  ImGui::TableNextRow();
  
  // Show variable groups
  ImGui::TableSetColumnIndex(0);
  
  ImGuiTableFlags innerTableFlags = 0;
  innerTableFlags |= ImGuiTableFlags_Resizable;
  innerTableFlags |= ImGuiTableFlags_ScrollY;
  innerTableFlags |= ImGuiTableFlags_PadOuterX;
  
  if (ImGui::BeginTable("##VariableGroups", 1, innerTableFlags))
  {
  }

  if (ImGui::BeginTable("##Variables", 2, innerTableFlags))
  {
  }
}

@redorav
Copy link
Author

redorav commented Aug 27, 2022

I managed to get it working like I wanted to. This is the final result. I also put in a log in the window using the docking API for good measure, it took me a while but I have it working now. The key for me was setting the ImGuiStyleVar_CellPadding to 0.0 before opening the enclosing table, like this:

// Remove the padding between cells for the beginning of the table
// This is to render the outer table completely invisible, except for the border
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0.0f, 0.0f));
bool beginContainerTable = ImGui::BeginTable("##ContainerTable", 2, containerTableFlags);
ImGui::PopStyleVar(); // ImGuiStyleVar_CellPadding

if (beginContainerTable)

I have an issue with the scrollbar but for that I'll open a new bug. Thanks for all the support and the wonderful work.

image

@redorav redorav closed this as completed Aug 27, 2022
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

3 participants