Closed ocornut closed 3 years ago
It seems that too many nested popups that use tables will crash with the error:
Assertion failed: _Current == 0 && _Count <= 1 && "Nested channel splitting is not supported. Please use separate instances of ImDrawListSplitter.", file imgui_draw.cpp, line 1444
I should note that in my actual project this same error occurs with just one popup after being open/closed roughly 20 or so times, but I've been unable to isolate that version of it (I suspect they have the same root cause).
In this sample, the error happens after opening 8 popups:
void Table(int count)
{
ImGui::SetNextWindowSize(ImVec2(300, 300));
char tableId[32]; sprintf(tableId, "table %d", count);
char popupId[32]; sprintf(popupId, "popup %d", count);
if (ImGui::BeginTable(tableId, 2))
{
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("Column 0");
ImGui::TableSetColumnIndex(1);
if (ImGui::Button("open"))
{
ImGui::OpenPopup(popupId);
}
if (ImGui::BeginPopupModal(popupId))
{
Table(count + 1);
ImGui::EndPopup();
}
ImGui::EndTable();
}
}
void Sample()
{
ImGui::SetNextWindowSize(ImVec2(300, 300));
ImGui::Begin("Sample");
Table(0);
ImGui::End();
}
Everyone:
I haved broken theTableGetSortSpecs()
API to make user explicitely clear the dirty flag:
const ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs();
if (sorts_specs && sorts_specs->SpecsChanged)
{
// [...] Perform sort
}
To:
ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs();
if (sorts_specs && sorts_specs->SpecsDirty)
{
// [...] Perform sort
sorts_specs->SpecsDirty = false; // Clear dirty flag
}
The reason being that TableGetSortSpecs()
had user-visible side-effect of effectively clearing that flag so multiple calls would lead to confusing bugs. Current version is less bug prone. See change 68ef531b06
Everyone: Prefer opening a new issue to submit a bug.
@sdhawk
It seems that too many nested popups that use tables will crash with the error:
Thank you for reporting with a nice repro! it was a bug holding on a table pointer accross resizing the pool used to store them. Our ImVector implementation by default would typically allocate 8 items ahead of them so bug wasn't noticeable. Fixed with 4cb0431e6.
I'll be making some more breaking changes toward trying to stabilizing the api for 1.80.
Recently
TableAutoHeaders()
to TableHeadersRow()
.ImGuiTableFlags_ScrollFreezeXXX
flags with TableSetupScrollFreeze()
api.ImGuiTableFlags_NoClipX to
ImGuiTableFlags_NoClip`.ImGuiTableSortSpecs
renamed bool SpecsChanged
to bool SpecsDirty
and made it the user responsability to clear that flag after sorting.Doing some more breaking as I'm hoping to promote this branch a lots more after releasing 1.79, toward merging the branch into master in 1.80.
TableNextCell()
to TableNextColumn()
. This makes lots more sense as there is a neat symmetry with the use of rows, the TableSetColumnIndex()
function and the old Columns API.TableNextRow()
to not automatically get into the first column. This makes the API generally more consistent.Those changes reflected recurrent feedback from first-time users, so I'm biting the bullet and changing things now.
Note that most the demo has been suggesting using TableSetColumnIndex()
so code written using that won't be affected.
- In most situations you can use TableNextRow() + TableSetColumnIndex(xx) to start appending into a column.
- If you are using tables as a sort of grid, where every columns is holding the same type of contents,
you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex().
TableNextColumn() will automatically wrap-around into the next row if needed.
- IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!
- Here's a summary of possible call flow:
----------------------------------------------------------------------------------------------------------------
TableNextRow() -> TableSetColumnIndex(0) -> Button("Hello 0") -> TableSetColumnIndex(1) -> Button("Hello 1") // OK
TableNextRow() -> TableNextColumn() Button("Hello 0") -> TableNextColumn() -> Button("Hello 1") // OK
TableNextColumn() Button("Hello 0") -> TableNextColumn() -> Button("Hello 1") // OK: TableNextColumn() automatically gets to next row!
TableNextRow() Button("Hello 0") ................................................ // Not OK! Missing TableSetColumnIndex() or TableNextColumn()!
----------------------------------------------------------------------------------------------------------------
@marinjurjevic Please post this in a new issue as instructed above and delete message here, thank you!
Recent changes to Tables:
ImGuiTableFlags_PreciseStretchWidths
for situations where we want stretch columns with same weight to be exactly the same width down to the pixels, otherwise by default the reminder width is spread across columns so some may be +1 pixel.Before shipping 1.80 the things I would like to solve are:
Everyone, I have pushed a few "major" breaking changes yesterday. I think they may be the final batch of breaking changes going in before going to master.
ImGuiTableFlags_SizingPolicyStretchX
to ImGuiTableFlags_ColumnsWidthStretch
.ImGuiTableFlags_SizingPolicyFixedX
to ImGuiTableFlags_ColumnsWidthFixed
.ImGuiTableColumnFlags_XXX
to ImGuiColumnFlags_XXX
, ImGuiTableRowFlags_XXX
to ImGuiRowFlags_XXX
.Sorry for the disturbance, hopefully this is for the good!
Is the plan to obsolete the old Column API completely or are both approaches sharing the same set of flags...
@frink the public columns API have no flags, only internal api has, see: 72de6f336070bb28281b758609f4097a58adf901 https://github.com/ocornut/imgui/issues/125#issuecomment-729996960
I stand corrected. I misread your post on #125 this morning.
Hello,
After some internal monologue, I have undid this specific change mentioned two days ago:
Renamed ImGuiTableColumnFlags_XXX to ImGuiColumnFlags_XXX, ImGuiTableRowFlags_XXX to ImGuiRowFlags_XXX.
Effectively nuked top-most commit 694f6cb from tables/ history. It's not worth creating the small inconsistency to simplify/shorten those symbols and they are not so often used, so backtracked on that decision.
I realized that one essential feature of tables was not demonstrated anywhere in the demo, and poorly documented. Added a bit of demo code now.
Tables with the same identifier share all settings (width, visibility, order, etc)
This is also de-facto a sensible workaround for creating contents that span an entire row (aka #3565) + ref #2136.
imgui_tables.cpp
file (#3513)ImGuiTableSortSpecsColumn
to ImGuiTableColumnSortSpecs
.TableGetHoveredColumn()
in favor of using TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered
.Tables have been merged into master today. I'll make a few extra changes, gather extra feedback, open a new thread soon (and close this one), and tag as 1.80 hopefully next week.
Hi, is there going to be a summary of the tables branch (and I guess it might be the new thread you mentioned in the above comment)?
Hi, is there going to be a summary of the tables branch (and I guess it might be the new thread you mentioned in the above comment)?
Yes I'm going to open a new threads when ready, but the top posts here + demo are giving a good summary already.
I found one niggle with sizing policy which I want to settle before tagging 1.80 hence the delay.
Related to table, since last week:
ImGuiTableFlags_SortTristate
to allow a third disabled state.ImGuiTableFlags_MultiSortable
to ImGuiTableFlags_SortMulti
. To support #3605 I made a little change to the default value and handling of the ImVec2 outer_size
parameter.
ImVec2 outer_size
previous default value to ImVec2(0.0f, 0.0f)
ImVec2 outer_size
new default value is ImVec2(-FLT-MIN, 0.0f)
(right-align)The new meaning of outer_size.x == 0.0f
is "automatic width".
If Scrolling is enabled or if any columns is set to Stretch, outer_size.x == 0.0f
is the same as outer_size == -FLT_MIN
(will right-align). If Scrolling is disabled and all columns are set to Non-Stretch, then outer_size.x == 0.0f
allows to create tables which don't use the full window width while not having to specify a width ahead:
Effectively this is unlikely to break much code as outer_size
is only required for scrolling tables.
(As a data point: The only things affected in the demo were demo tables which had a toggle to switch between scrolling and not-scrolling, and therefore had specific height provided and yet could have their scrolling disabled, which is not likely to appear in real code.)
Just a positive note. Tables work well and are very functional, I especially like fixed row and column headers and fast display of even large tables. The architecture is clean and understandable. During the last months, judging by GitHub updates, the development in this area has been fast, now I am looking forward to the next stable version to test. Thank you:)
I know the joke is getting old now :) but last month while looking at a totally unrelated thing (#1149) I came up with a few realization and situations where the sizing policies were inadequate, which eventually got me into a larger/deeper exploration of various sizing-related ideas and a mild refactor of the exposed policilies. As a result I've again broken the API (but only in a minor way and only if you specified a table sizing policy explicitly).
TL;DR:
ImGuiTableFlags_ColumnsWidthFixed
> ImGuiTableFlags_SizingFixedFit
ImGuiTableFlags_ColumnsWidthStretch
> ImGuiTableFlags_SizingStretchSame
.
If you are using Tables I would appreciate if you could update to latest to make sure everything's alright. And then hopefully we can tag 1.80....
Here's a run down of table sizing policies:
// Sizing Policy (read above for defaults)
ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width.
ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible.
ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
New section in the demo:
e.g. a use of ImGuiTableFlags_SizingStretchProp
:
There are many details under the hood which I don't have the energy to explain right now (most you don't really need to know until you hit very specific use cases) but added variety of comments and added myself more notes.
Also, previously default table policy in an auto-resizing window (e.g. a tooltip) would lead to stretching columns with same weight which was wholly inadequate, we're now using ImGuiTableFlags_SizingFixedFit
by default in an auto-resizing window.
One last thing I'd like to do is clarify per-column Auto vs Fixed policies and the effect of some of the internals unexposed api to override current width (not default width).
Bonus fact: Our regression tests are now covering 97% lines of imgui_tables.cpp, aka 61 uncovered and many are asserts/error handlers.
Quick test Dear ImGui, 9.1.2021 docking branch, commit tag 70703da7829ba74a92a08fe3c6fe0664c39c97c9
I switched to use this version, all started working quickly. Notes:
Based on the quick test, all good with the newest table code. Best regards, Pekka
@iocafe
ImGuiTableFlags_SizingPolicyStretchX -> ImGuiTableFlags_SizingStretchProp
Note that the old ImGuiTableFlags_SizingPolicyStretchX
is == ImGuiTableFlags_SizingStretchSame
. ImGuiTableFlags_SizingStretchProp
is a slightly different behavior.
TableGetHoveredColumn() now internal, included "imgui_internal.h". (I need to look for better way to do this some point).
Post above says: "Removed TableGetHoveredColumn() in favor of using TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered."
I hit to 64 columns limit but decided to live with this for now. Support to more columns maybe in future, the original code has preparation for more columns (typedef ImGuiTableColumnIdx and draw channels). I hope for a real tested version sometime in the future (much preferred over my own quick and dirty patches).
Yes I think we'll support it eventually.
Thank you for help and advice. When I work with ImGui, it feels like it is on the verge of break though to much wider use. Recent docking and table features extended the application area to office, database and data manipulation. It is good, fast and clean, and provides "game like" immediate response to the end user. It is open source, can be integrated easily to any application project and be adopted to run on practically any modern hardware. And most of all, it is ready and reliable. Many thanks, tables are great!
On Mon, Jan 11, 2021 at 1:24 PM omar notifications@github.com wrote:
@iocafe https://github.com/iocafe
ImGuiTableFlags_SizingPolicyStretchX -> ImGuiTableFlags_SizingStretchProp
Note that the old ImGuiTableFlags_SizingPolicyStretchX is == ImGuiTableFlags_SizingStretchSame. ImGuiTableFlags_SizingStretchProp is a slightly different behavior.
TableGetHoveredColumn() now internal, included "imgui_internal.h". (I need to look for better way to do this some point).
Post above says: "Removed TableGetHoveredColumn() in favor of using TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered."
I hit to 64 columns limit but decided to live with this for now. Support to more columns maybe in future, the original code has preparation for more columns (typedef ImGuiTableColumnIdx and draw channels). I hope for a real tested version sometime in the future (much preferred over my own quick and dirty patches).
Yes I think we'll support it eventually.
- The ImU64 mask will be changed to something like ImBitArray or ImBitVector. Neither are currently satisfactory as one would require a worst-case limit and the other would heap-allocate. Instead we will allocate everything we need for the 4 masks inside the RawData single-alloc and call the lower-level ImBitArrayXXX functions directly. The MAIN purpose of all those packed masks is to avoid touching unnecessary cache-lines for non-visible columns (otherwise we could naively move all those flags as bool stored into each columns, but that would defeat their purpose).
- I would like to move ImDrawSplitter and some other transient data out of ImGuiTable and into a structure shared by all tables for a given recursion level, that will alleviate the recurrent cost of high-columns tables.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ocornut/imgui/issues/2957#issuecomment-758136035, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANCVOSGWHRVRE7EO6NPYHZ3SZM64NANCNFSM4KBOCHAQ .
TABLES ARE NOW MERGED, MOVING THIS TO #3740
I have pushed an experimental
tables
branch: https://github.com/ocornut/imgui/tree/tables Providing a long awaited full-featured replacement to the old "Columns" API (#125).I have been working on this for an embarassingly looong time.. What seemingly started as "let's refactor columns" became a multi-month thing with many rewrites/iterations. A large portion of this work been sponsored by Blizzard Entertainment. Several internal changes pushed to 1.71-1.74 were in preparation for this as I often try to have changes trickle down to master whenever possible to reduce complication of branching.
Please read <3 (this post will be occasionally updated)
Basic Usage: https://github.com/ocornut/imgui/issues/2957#issuecomment-569725733
TODO List: https://github.com/ocornut/imgui/issues/2957#issuecomment-569726095
WIP API breaking changes Sept 2020 https://github.com/ocornut/imgui/issues/2957#issuecomment-698317698
Question? Feedback? Bug report? Feature request? Please create a NEW ISSUE!
Status
Looking for early testers
Git Flow
tables
(https://github.com/ocornut/imgui/tree/tables).Features
Some screenshots