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

New Tables API (1.80) #3740

Open
ocornut opened this issue Jan 21, 2021 · 12 comments
Open

New Tables API (1.80) #3740

ocornut opened this issue Jan 21, 2021 · 12 comments

Comments

@ocornut
Copy link
Owner

ocornut commented Jan 21, 2021

This is a followup to the original Tables thread #2957
Now that Tables are merged in master and released as part of 1.80 I am republishing this in a cleaned version, without all the intermediate changes.

See release note for 1.80 !

If you have questions, bug reports, feature requests: please open a new thread!

Links

Usage, API
#3740 (comment)

Issues / Todo List:
#3740 (comment)

Features include e.g.

  • Scrolling on both axises
  • Possibility to freeze/lock rows or columns so they are always visible with scrolling
  • Headers (which can be customized)
  • Cells can contains anything (you can output multiple widgets, etc.) it's a regular canvas for your contents.
  • Various per-table sizing policy and per-column overrides.
  • Columns can be reordered
  • Columns can be hidden
  • Columns can be resized
  • Columns can be sorted (actual data sorting is done by user, api gives you the sort specs/infos you need)
  • Various bordering and padding options
  • Per-Columns flags (e.g. honor indent)
  • Borders and odd/even row background colors options
  • Clipper can be used on vertical axis (per column clipping possible as visibility is provided to user)
  • Saved settings (storage is font/dpi change friendly)
  • Context menu

image

image

image

1.90 angled headers: (#6917)
table angled headers 2

@ocornut
Copy link
Owner Author

ocornut commented Jan 21, 2021

Reading list

Basic demo

// Here we will showcase three different ways to output a table.
// They are very simple variations of a same thing!

// [Method 1] Using TableNextRow() to create a new row, and TableSetColumnIndex() to select the column.
// In many situations, this is the most flexible and easy to use pattern.
if (ImGui::BeginTable("table1", 3))
{
    for (int row = 0; row < 4; row++)
    {
        ImGui::TableNextRow();
        for (int column = 0; column < 3; column++)
        {
            ImGui::TableSetColumnIndex(column);
            ImGui::Text("Row %d Column %d", row, column);
        }
    }
    ImGui::EndTable();
}

// [Method 2] Using TableNextColumn() called multiple times, instead of using a for loop + TableSetColumnIndex().
// This is generally more convenient when you have code manually submitting the contents of each columns.
if (ImGui::BeginTable("table2", 3))
{
    for (int row = 0; row < 4; row++)
    {
        ImGui::TableNextRow();
        ImGui::TableNextColumn();
        ImGui::Text("Row %d", row);
        ImGui::TableNextColumn();
        ImGui::Text("Some contents");
        ImGui::TableNextColumn();
        ImGui::Text("123.456");
    }
    ImGui::EndTable();
}

// [Method 3] We call TableNextColumn() _before_ each cell. We never call TableNextRow(),
// as TableNextColumn() will automatically wrap around and create new roes as needed.
// This is generally more convenient when your cells all contains the same type of data.
if (ImGui::BeginTable("table3", 3))
{
    for (int item = 0; item < 14; item++)
    {
        ImGui::TableNextColumn();
        ImGui::Text("Item %d", item);
    }
    ImGui::EndTable();
}

API (as of January 2021)

// Tables
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Full-featured replacement for old Columns API.
// - See Demo->Tables for demo code.
// - See top of imgui_tables.cpp for general commentary.
// - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags.
// The typical call flow is:
// - 1. Call BeginTable().
// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults.
// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows.
// - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data.
// - 5. Populate contents:
//    - In most situations you can use TableNextRow() + TableSetColumnIndex(N) 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!
//    - Summary of possible call flow:
//        --------------------------------------------------------------------------------------------------------
//        TableNextRow() -> TableSetColumnIndex(0) -> Text("Hello 0") -> TableSetColumnIndex(1) -> Text("Hello 1")  // OK
//        TableNextRow() -> TableNextColumn()      -> Text("Hello 0") -> TableNextColumn()      -> Text("Hello 1")  // OK
//                          TableNextColumn()      -> Text("Hello 0") -> TableNextColumn()      -> Text("Hello 1")  // OK: TableNextColumn() automatically gets to next row!
//        TableNextRow()                           -> Text("Hello 0")                                               // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
//        --------------------------------------------------------------------------------------------------------
// - 5. Call EndTable()

// Begin appending into a table. Only call EndTable() if BeginTable() returns true!
bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
void EndTable();

// Append into the first cell of a new row.
void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); 

// Append into the next column (or first column of next row if currently in last column). Return true when 
bool TableNextColumn();column is visible.

// Append into the specified column. Return true when column is visible.
bool TableSetColumnIndex(int column_n);

// Tables: Headers & Columns declaration
// - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc.
// - Use TableHeadersRow() to create a header row and automatically submit a TableHeader() for each column.
//   Headers are required to perform: reordering, sorting, and opening the context menu.
//   The context menu can also be made available in columns body using ImGuiTableFlags_ContextMenuInBody.
// - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in
//   some advanced use cases (e.g. adding custom widgets in header row).
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
void TableHeadersRow();                          // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
void TableHeader(const char* label);             // submit one header cell manually (rarely used)
void TableAngledHeadersRow();                    // submit a row with angled headers for every column with the ImGuiTableColumnFlags_AngledHeader flag. MUST BE FIRST ROW.

// Tables: Sorting & Miscellaneous functions
// - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.
//   When 'sort_specs->SpecsDirty == true' you should sort your data. It will be true when sorting specs have
//   changed since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting,
//   else you may wastefully sort your data every frame!
// - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index.
ImGuiTableSortSpecs*  TableGetSortSpecs();                        // get latest sort specs for the table (NULL if not sorting).  Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
int                   TableGetColumnCount();                      // return number of columns (value passed to BeginTable)
int                   TableGetColumnIndex();                      // return current column index.
int                   TableGetRowIndex();                         // return current row index.
const char*           TableGetColumnName(int column_n = -1);      // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1);     // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
void                  TableSetColumnEnabled(int column_n, bool v);// change user accessible enabled/disabled state of a column. Set to false to hide the column. User can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
void                  TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1);  // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.

ImGuiTableFlags

// Flags for ImGui::BeginTable()
// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out!
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
//   Read comments/demos carefully + experiment with live demos to get acquainted with them.
// - The DEFAULT sizing policies are:
//    - Default to ImGuiTableFlags_SizingFixedFit    if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize.
//    - Default to ImGuiTableFlags_SizingStretchSame if ScrollX is off.
// - When ScrollX is off:
//    - Table defaults to ImGuiTableFlags_SizingStretchSame -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch with same weight.
//    - Columns sizing policy allowed: Stretch (default), Fixed/Auto.
//    - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all).
//    - Stretch Columns will share the remaining width.
//    - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors.
//      The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
//      (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
// - When ScrollX is on:
//    - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed
//    - Columns sizing policy allowed: Fixed/Auto mostly.
//    - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
//    - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop.
//    - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
//      If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again.
// - Read on documentation at the top of imgui_tables.cpp for details.
enum ImGuiTableFlags_
{
    // Features
    ImGuiTableFlags_None                       = 0,
    ImGuiTableFlags_Resizable                  = 1 << 0,   // Enable resizing columns.
    ImGuiTableFlags_Reorderable                = 1 << 1,   // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
    ImGuiTableFlags_Hideable                   = 1 << 2,   // Enable hiding/disabling columns in context menu.
    ImGuiTableFlags_Sortable                   = 1 << 3,   // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
    ImGuiTableFlags_NoSavedSettings            = 1 << 4,   // Disable persisting columns order, width and sort settings in the .ini file.
    ImGuiTableFlags_ContextMenuInBody          = 1 << 5,   // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().

    // Decorations
    ImGuiTableFlags_RowBg                      = 1 << 6,   // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent of calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
    ImGuiTableFlags_BordersInnerH              = 1 << 7,   // Draw horizontal borders between rows.
    ImGuiTableFlags_BordersOuterH              = 1 << 8,   // Draw horizontal borders at the top and bottom.
    ImGuiTableFlags_BordersInnerV              = 1 << 9,   // Draw vertical borders between columns.
    ImGuiTableFlags_BordersOuterV              = 1 << 10,  // Draw vertical borders on the left and right sides.
    ImGuiTableFlags_BordersH                   = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
    ImGuiTableFlags_BordersV                   = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
    ImGuiTableFlags_BordersInner               = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
    ImGuiTableFlags_BordersOuter               = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
    ImGuiTableFlags_Borders                    = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter,   // Draw all borders.
    ImGuiTableFlags_NoBordersInBody            = 1 << 11,  // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
    ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12,  // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style

    // 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().

    // Sizing Extra Options
    ImGuiTableFlags_NoHostExtendX              = 1 << 16,  // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
    ImGuiTableFlags_NoHostExtendY              = 1 << 17,  // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
    ImGuiTableFlags_NoKeepColumnsVisible       = 1 << 18,  // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
    ImGuiTableFlags_PreciseWidths              = 1 << 19,  // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.

    // Clipping
    ImGuiTableFlags_NoClip                     = 1 << 20,  // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().

    // Padding
    ImGuiTableFlags_PadOuterX                  = 1 << 21,  // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
    ImGuiTableFlags_NoPadOuterX                = 1 << 22,  // Default if BordersOuterV is off. Disable outer-most padding.
    ImGuiTableFlags_NoPadInnerX                = 1 << 23,  // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).

    // Scrolling
    ImGuiTableFlags_ScrollX                    = 1 << 24,  // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
    ImGuiTableFlags_ScrollY                    = 1 << 25,  // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.

    // Sorting
    ImGuiTableFlags_SortMulti                  = 1 << 26,  // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
    ImGuiTableFlags_SortTristate               = 1 << 27,  // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
    // Miscellaneous
    ImGuiTableFlags_HighlightHoveredColumn     = 1 << 28,  // Highlight column headers when hovered (may evolve into a fuller highlight)
};

ImGuiTableColumnFlags

// Flags for ImGui::TableSetupColumn()
enum ImGuiTableColumnFlags_
{
    // Input configuration flags
    ImGuiTableColumnFlags_None                  = 0,
    ImGuiTableColumnFlags_Disabled              = 1 << 0,   // Overriding/master disable flag: hide column, won't show in context menu (unlike calling TableSetColumnEnabled() which manipulates the user accessible state)
    ImGuiTableColumnFlags_DefaultHide           = 1 << 1,   // Default as a hidden/disabled column.
    ImGuiTableColumnFlags_DefaultSort           = 1 << 2,   // Default as a sorting column.
    ImGuiTableColumnFlags_WidthStretch          = 1 << 3,   // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp).
    ImGuiTableColumnFlags_WidthFixed            = 1 << 4,   // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable).
    ImGuiTableColumnFlags_NoResize              = 1 << 5,   // Disable manual resizing.
    ImGuiTableColumnFlags_NoReorder             = 1 << 6,   // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
    ImGuiTableColumnFlags_NoHide                = 1 << 7,   // Disable ability to hide/disable this column.
    ImGuiTableColumnFlags_NoClip                = 1 << 8,   // Disable clipping for this column (all NoClip columns will render in a same draw command).
    ImGuiTableColumnFlags_NoSort                = 1 << 9,   // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
    ImGuiTableColumnFlags_NoSortAscending       = 1 << 10,  // Disable ability to sort in the ascending direction.
    ImGuiTableColumnFlags_NoSortDescending      = 1 << 11,  // Disable ability to sort in the descending direction.
    ImGuiTableColumnFlags_NoHeaderLabel         = 1 << 12,  // TableHeadersRow() will not submit horizontal label for this column. Convenient for some small columns. Name will still appear in context menu or in angled headers.
    ImGuiTableColumnFlags_NoHeaderWidth         = 1 << 13,  // Disable header text width contribution to automatic column width.
    ImGuiTableColumnFlags_PreferSortAscending   = 1 << 14,  // Make the initial sort direction Ascending when first sorting on this column (default).
    ImGuiTableColumnFlags_PreferSortDescending  = 1 << 15,  // Make the initial sort direction Descending when first sorting on this column.
    ImGuiTableColumnFlags_IndentEnable          = 1 << 16,  // Use current Indent value when entering cell (default for column 0).
    ImGuiTableColumnFlags_IndentDisable         = 1 << 17,  // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
    ImGuiTableColumnFlags_AngledHeader          = 1 << 18,  // TableHeadersRow() will submit an angled header row for this column. Note this will add an extra row.

    // Output status flags, read-only via TableGetColumnFlags()
    ImGuiTableColumnFlags_IsEnabled             = 1 << 20,  // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
    ImGuiTableColumnFlags_IsVisible             = 1 << 21,  // Status: is visible == is enabled AND not clipped by scrolling.
    ImGuiTableColumnFlags_IsSorted              = 1 << 22,  // Status: is currently part of the sort specs
    ImGuiTableColumnFlags_IsHovered             = 1 << 23,  // Status: is hovered by mouse
};

ImGuiTableRowFlags

// Flags for ImGui::TableNextRow()
enum ImGuiTableRowFlags_
{
    ImGuiTableRowFlags_None                         = 0,
    ImGuiTableRowFlags_Headers                      = 1 << 0    // Identify header row (set default background color + width of its contents accounted different for auto column width)
};

ImGuiTableBgTarget

// Enum for ImGui::TableSetBgColor()
// Background colors are rendering in 3 layers:
//  - Layer 0: draw with RowBg0 color if set, otherwise draw with ColumnBg0 if set.
//  - Layer 1: draw with RowBg1 color if set, otherwise draw with ColumnBg1 if set.
//  - Layer 2: draw with CellBg color if set.
// The purpose of the two row/columns layers is to let you decide if a background color change should override or blend with the existing color.
// When using ImGuiTableFlags_RowBg on the table, each row has the RowBg0 color automatically set for odd/even rows.
// If you set the color of RowBg0 target, your color will override the existing RowBg0 color.
// If you set the color of RowBg1 or ColumnBg1 target, your color will blend over the RowBg0 color.
enum ImGuiTableBgTarget
{
    ImGuiTableBgTarget_None                     = 0,
    ImGuiTableBgTarget_RowBg0                   = 1,        // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
    ImGuiTableBgTarget_RowBg1                   = 2,        // Set row background color 1 (generally used for selection marking)
    ImGuiTableBgTarget_CellBg                   = 3,        // Set cell background color (top-most color)
};

@ocornut
Copy link
Owner Author

ocornut commented Jan 21, 2021

Issues / Todo list

(copied from old #2957, removed all done issues)

Some of the stuff remaining in my current todo list

General

  • B. Fast path for _NoClip + minimum column size based on contents size
  • B. Detect that a cell is hovered/clicked/dragged from? How can we expose GetRectCellRect() without explicit row height? (-> is there a way to know when a table cell is hovered? #6588)
  • B. InnerWidth parameter is confusing, with ScrollX and < OuterWidth also mess up with clipping.
  • B. Spanning multiple columns and/or multiple rows. (issue 3565)
  • B. Using Separator the same way as in Columns?
  • B. Experiment with drag and drop patterns (e.g. drag row from left-most header cell)
  • B. Append in same column multiple times per row (suggestion: store BeginColumnMask in table, clear on BeginRow, store/reuse Y position on Begin/EndCell). Only init ColumnsOffset.x and column->CursorPosY on first use of column).
  • B. Visible one frame lag with Fixed columns appearing while window is still showing.
  • C. Glitch when clipped while host ScrollbarY status change (repro by toggling "Advanced->Options" and seeing the table scroll down)
  • C. Programmatic control: should be able to reorder, hide, sort, resize with public API.
  • C. Provide feedback to code on reorder (visually contiguous selection patterns may need to clear selection or rely on display order).
  • C. Support ScrollX without ScrollY while properly extending the height of the child window.
  • C. Multi/synced instances: Same frame sync issue with: Toggling visibility in context menu, Size all columns in context menu
  • C. Multi/synced instances: Validate and document possible edge cases (what happens when tables have heterogeneous widths? variable count?)

Sizing behaviors

  • B. If user outputs to clipped column (ignoring the return value) the content width should feed in size instead of being ignored.
  • B. Resize height of outer container from lower border (could also be a BeginChild feature!)
  • B. Auto-resize of a single stretch column could redistribute width to multiple siblings.
  • B. Simple non-border n-ways should aim to use matching outer cliprect for natural merge.
  • C. Sizing: api to set per-column minimum column width?

Borders

  • B. Borders: Rework borders drawing code, currently a bit too complex and brittle.
  • B. Borders: Compact table demo still have issue with vertical borders
  • B. Borders: Ideally per cell borders would allow e.g. joining columns/cells. Bit of a high-bar but could be a good reference points when redesigning borders code.
  • B. Figure out Selection patterns/features and provide a demo.
  • B. Per-column background color overrides.
  • B. NoBordersInBody and NoBordersInBodyUntilResize could be regular style variables/colors.
  • B. Style: Decide how we express border colors in the style (or if we can't infer it from Separator+WindowBg color)
  • C. Borders: configure the presence of borders over the freezing line? (e.g. _NoBordersOnFreezingLine)

Keyboard/Gamepad Navigation

  • B. Nav: Fixes for using navigation with scroll freeze (either axis). Alter InnerRect, standardize decoration size in windows?
  • B. Nav: Should be able to programmatically make a given column or row visible.
  • B. Nav: Navigation support for resizing, context menu? (can't right-click)
  • B. ImGui::ScrollToBringRectIntoView seems to ignore frozen columns/rows. A ImGui::ScrollToBringTableCellIntoView function would be even better!

Headers, context menu

  • B. Reorder: when going past mid-point of next columns + improve reorder past the scrolling view.
  • C. Headers: Using TableHeader() in any cell (generally first column)
  • B. AngledHeader: AngledHeadersExtraWidth not applied in all situations.
  • B. AngledHeader: render glitchy with FreezeColumn in Advanced demo, not in Angled Header demo. Why?

Documentation

  • B. Columns to Table conversion guide.

Demo

@PazerOP
Copy link
Contributor

PazerOP commented Jan 21, 2021

I was potentially interested in being an early adopter for this API, but unfortunately not interested enough that I would be able to spend time implementing something with an API that is still going to have significant breaking changes made to it.

I saw in the last issue there were breaking changes made as of this month, are there currently plans to have additional breaking changes before the API is finalized for 1.80?

I realize it's not reasonable for you to promise that you won't make any more breaking changes, but was just curious if you still had some things in mind you wanted to change.

@ocornut
Copy link
Owner Author

ocornut commented Jan 21, 2021

I was potentially interested in being an early adopter for this API,

Early adopting the API was in January 2020. It's rather stable now.
The breaking changes were made before this release. 1.80 is out.

The release note state: "Please note the Tables API is still in Beta. What it means is we are sliiiightly more likely than usual to make small changes to the API. If we do they'll be cautious, documented, with redirecting helpers, as usual.".

@PazerOP
Copy link
Contributor

PazerOP commented Jan 21, 2021

1.80 is out.

Oops, my mistake!

I'll give this a try when I can, I've been looking forward to enhanced tables/columns support for a while now.

@sanbox-irl
Copy link

Several functions in the tables api can segfault if called when no table is currently being ran. those segfaults are a bit hard to debug.

two thoughts:

  1. Can we have asserts within these functions to point us to the problem? Hopefully these would also replace the dummy return false/0 in the getters too.
  2. If we can't do that, I use imgui through imgui-rs (I also maintain that shim) -- is there a way to check if there is a currently running table right now? on the rust side, I don't mind adding such a assertions, since rust developers are much more allergic (or at least, loud) about segfaults than when I'm in C++.

I can also open a separate issue if that's easier for you!

@YusufSuleman
Copy link

I can now make the Minecraft Inventory easily

@dufferzafar
Copy link

@ocornut Is it possible to create an editable cell? (or maybe when user double clicks a normal cell, it becomes editable) where a user can make their entries.

Is there a demo for such a functionality, I didn't find it in the tables demo.

@syoyo
Copy link

syoyo commented Dec 28, 2021

@dufferzafar Table cell is just a canvas, so you can embed any GUI widgets. You can create a table with editable cells like this:

        if (ImGui::BeginTable("table1", 3))
        {
            for (int row = 0; row < 4; row++)
            {
                ImGui::TableNextRow();
                for (int column = 0; column < 3; column++)
                {
                    ImGui::TableSetColumnIndex(column);
                    //ImGui::Text("Row %d Column %d", row, column);

                    ImGui::PushID(row * 3 + column); // assign unique id
                    ImGui::InputFloat("##v", &values[row][column]);
                    ImGui::PopID();
                }
            }
            ImGui::EndTable();
        }

Screenshot from 2021-12-28 16-07-24

"Double-click, then edit a cell" feature will require an extra work.

@dufferzafar
Copy link

@syoyo Thanks for your help. Will try this!

@ocornut ocornut unpinned this issue Jan 20, 2022
Sebanisu added a commit to Sebanisu/Field-Map-Editor that referenced this issue Dec 13, 2022
…. Then it'll remove the ones with all 0s.

ocornut/imgui#3740
I was trying to eliminate empty tiles. That was kind of a headache. I forgot to divide by 16. So I spent hours like, "why isn't this working?!"  Had to write a little code to show what is in the tiles afterwards. Though they can't be saved as is. Still have to calculate the source x, y, texture_page, and offset the x,y as the center of the drawn image is 0,0 (atleast on most images).
ocornut added a commit that referenced this issue Jul 13, 2023
…#6588, #3740)

Works with one-frame delay inconsistent with other functions, may be too bug-prone.
@phraktle
Copy link

Is there a suggested way to create a sticky footer row (summary) for a table?

@ocornut
Copy link
Owner Author

ocornut commented Mar 12, 2024

Is there a suggested way to create a sticky footer row (summary) for a table?

Please open new issues so we can easily refer to them.

Ciachociech added a commit to Ciachociech/imgui that referenced this issue Jul 24, 2024
* Version 1.90.8

* Version 1.90.9 WIP

* Internals: renamed HoveredIdDisabled to HoveredIdIsDisabled for consistency.

* Examples: GLFW+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR (ocornut#7671)

* Examples: SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR (ocornut#7671)

* Removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages).

* Internals: made ImLowerBound() accessible in internals + take a span. + rearrange child/popup/tooltips section.

Because upcoming rework of ImGuiSelectionBasicStorage will want to do a lower bound on a span.

* IO: do not disable io.ConfigWindowsResizeFromEdges when ImGuiBackendFlags_HasMouseCursors is not set by backend.

Amend 42bf149

* Style: (Breaking) renamed ImGuiCol_TabActive -> ImGuiCol_TabSelected, ImGuiCol_TabUnfocused -> ImGuiCol_TabDimmed, ImGuiCol_TabUnfocusedActive -> ImGuiCol_TabDimmedSelected.

Amend ocornut#261, ocornut#351

* TabBar, Style: added ImGuiTabBarFlags_DrawSelectedOverline and ImGuiCol_TabSelectedOverline, ImGuiCol_TabDimmedSelectedOverline.

* Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern. (ocornut#143)

Amend 0c6e260

* Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame.

* Internals: added ImGuiContext::ContextName optionally used by debug log and to facilitate debugging.

* Drag and Drop: comments, debug log entries.

* Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern assume a mouse button being pressed. (ocornut#143)

* Drag and Drop: (Breaking) renamed ImGuiDragDropFlags_SourceAutoExpirePayload to ImGuiDragDropFlags_PayloadAutoExpire. (ocornut#1725, ocornut#143)

* Drag and Drop: Added ImGuiDragDropFlags_PayloadNoCrossContext and ImGuiDragDropFlags_PayloadNoCrossProcess flags.

* Ignore .ini file with other suffixes.

* Fixed build warning.

* IO: added ClearInputMouse(). made ClearInputKeys() not clear mouse data. (ocornut#4921)

Amend 6aa408c

* IO: added ImGuiConfigFlags_NoKeyboard for consistency and convenience. (ocornut#4921)

# Conflicts:
#	imgui.h
#	imgui_demo.cpp

* Nav: CTRL+Tab overlay display context name if any.

* Internals: storing HoveredWindowBeforeClear for use by multi-context compositor drag and drop propagation.

# Conflicts:
#	imgui.cpp
#	imgui_internal.h

* (Breaking) Move ImGuiWindowFlags_NavFlattened to ImGuiChildFlags_NavFlattened. (ocornut#7687)

* Backends: SDL3: Follow SDL3 removal of keysym field in SDL_KeyboardEvent (ocornut#7729)

* Demo: Style Editor: clarify how _CalcCircleAutoSegmentCount() doesn't always get exact final segment count. (ocornut#7731)

* Backends: Vulkan: Remove Volk/ from volk.h #include directives (ocornut#7722, ocornut#6582, ocornut#4854)

* Metrics/Debugger: Browsing a Storage perform hover lookup on identifier.

* Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends.

* Backends: SDL3: Update for SDL_StartTextInput()/SDL_StopTextInput() API changes. (ocornut#7735)

* Examples: undo adding SDL3 example to Visual Studio sln.

* Backends: OSX: build fix. Amend 32f9dfc

* ImGuiStorage: tweak impl for BuildSortByKey().

* Inputs: fixed using Shortcut() or SetNextItemShortcut() within a disabled block bypassing the disabled state. (ocornut#7726)

* Tables: moved TableGetHoveredColumn() to public API. (ocornut#7715, ocornut#3740)

* Windows: BeginChild(): fixed a glitch when during a resize of a child window which is tightly close to the boundaries of its parent. (ocornut#7706)

* Nav: store NavJustMovedToIsTabbing + shuffle a few nav related fields.

(for usage by multi-select)

* Backends: OpenGL2, OpenGL3: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (ocornut#7748)

Analogous to change to Vulkan backend in 1.90.

* Backends: Win32: Fixed warning with old MinGW/GCC versions.

* Drags: added ImGuisliderFlags_WrapAround flag for DragInt(), DragFloat() etc. (ocornut#7749)

* Fix typo, rename ImGuisliderFlags_WrapAround flag to ImGuiSliderFlags_WrapAround. (ocornut#7752, ocornut#7749)

* Checkbox: minor tidying up to simplify work on multi-select branch.

* Backends: Allegro5: Correctly handle unstable bit in version checks (ocornut#7755)

* Backends: SDLRenderer3: Update for SDL_RenderGeometryRaw() API changes.

* Backends: SDL3: update for SDL_SetTextInputRect() -> SDL_SetTextInputArea() api change. (ocornut#7760, ocornut#7754)

* Examples: SDL3: Remove use of SDL_HINT_IME_NATIVE_UI.

* Disabled: Reworked 1.90.8 behavior of Begin() not inheriting current BeginDisabled() state. Only tooltip are clearing that state. (ocornut#211, ocornut#7640)

* imgui_freetype: fixed divide by zero while handling FT_PIXEL_MODE_BGRA glyphs. (ocornut#7267, ocornut#3369)

* IO: do not claim io.WantCaptureMouse=true on the mouse release frame of a button which was pressed over void.  (ocornut#1392)

* Version 1.90.9

* Version 1.91.0 WIP

* Backends: SDL3: Update for API changes: SDLK_x renames and SDLK_KP_x removals (ocornut#7761, ocornut#7762)

Also updated function signature in SDL2 backend to match and because it is expected we will use that data (as per ocornut#7672)

* Backends: SDL3: Updated comments (IME seems fixed in SDL3). Added SDL3 examples to Visual Studio solution.

* Debug Tools: Added IMGUI_DEBUG_LOG(), ImGui::DebugLog() in public API. (ocornut#5855)

* Debug Log: Added "Configure Outputs.." button. (ocornut#5855)

* Backends: SDL3: add default case to fix warnings. (ocornut#7763)

* Demo: changed style editor inline block to its own window.

* IO: added io.PlatformOpenInShellFn handler to open a link/folder/file in OS shell, added IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS. (ocornut#7660)

* (Breaking) IO, IME: renamed platform IME hook io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() and added explicit context.

* Commented out obsolete ImGuiModFlags and ImGuiModFlags_XXX values (renamed to ImGuiKeyChord and ImGuiMod_XXX in 1.89). (ocornut#4921, ocornut#456)

* Build fix for non Windows platforms.

* IO: disable default io.PlatformOpenInShellFn() implementation on iPhone, as compiler errors that system() is not available on iOS.

* Internals: added FontScale storage.

* Added TextLink(), TextLinkOpenURL() hyperlink widgets. (ocornut#7660)

* Internals: added FontScale storage (amend 0f63d3e).

* Backends: GLFW,SDL2: Added ioPlatformOpenInShellFn handler for web/Emscripten versions. (ocornut#7660)

* IO: amend PlatformOpenInShellFn specs to return a bool. (ocornut#7660)

Amend 8f36798

* Misc tweaks, comments.

* TreeNode: rename/rework ImGuiNavTreeNodeData system to be usable by more features. (ocornut#2920, ocornut#1131, ocornut#7553)

Reworked to it is easier during TreeNode code to request extra data to be stored.

* Fixed Unix version of PlatformOpenInShellFn_DefaultImpl. (ocornut#7772, ocornut#7660)

+ Enable on non-iPhone macOS builds

* DemosFix typo in help text in demo Tables/Borders (ocornut#7780)

The help text for flags had a "V" flag duplicated, this change corrects it to the missing "H" flag.

* Backends: Win32: fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN (ocornut#7768, ocornut#4858, ocornut#2622)

Amend 0755767

The `ImGui_ImplWin32_UpdateKeyModifiers()` function maps `ImGuiMod_Super` to `VK_APPS`, the "Application" key located between the Right Windows (Super) and Right Control keys on the keyboard, see https://conemu.github.io/en/AppsKey.html

This means that when using `ImGui::GetIO().KeySuper` to try to get the down state of the `VK_RWIN` or `VK_LWIN` keys, it'll always return FALSE when either of those keys are held down, and only return TRUE when `VK_APPS` is held down.

* Backends: GLFW+Emscripten: (Breaking) Renamed ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to ImGui_ImplGlfw_InstallEmscriptenCallbacks(), added GLFWwindow* parameter. (ocornut#7647, ocornut#7600)

+ Fixed Emscripten warning when using mouse wheel on some setups.

* Backends: GLFW+Emscripten: Added support for GLFW3 contrib port. (ocornut#7647)

* Backends: GLFW+Emscripten: Fixed build (ocornut#7647)

* Examples: SDL3+OpenGL: Update for API changes: SDL_GL_DeleteContext() renamed to SDL_GL_DestroyContext().

* Fix definition check (ocornut#7793)

* Backends: SDL3: Update for API changes: SDL_GetProperty() change to SDL_GetPointerProperty(). (ocornut#7794)

* Backends: SDL3: fixed typo leading to PlatformHandleRaw not being set leading to SHOWNA path not working for multi-viewports.

* Internals: Added TreeNodeIsOpen() to facilitate discoverability. (ocornut#7553, ocornut#1131, ocornut#2958, ocornut#2079, ocornut#722)

* Added ImGuiDataType_Bool for convenience.

* Demo: Reworked "Property Editor" demo in a manner that more ressemble the tree data and struct description data that a real application would want to use.

* Added PushItemFlag(), PopItemFlag(), ImGuiItemFlags.

* (Breaking) Obsoleted PushButtonRepeat()/PopButtonRepeat() in favor of using new PushItemFlag()/PopItemFlag() with ImGuiItemFlags_ButtonRepeat.

* Added ImGuiItemFlags_AutoClosePopups as a replacement for internal's ImGuiItemFlags_SelectableDontClosePopup. (ocornut#1379, ocornut#1468, ocornut#2200, ocornut#4936, ocornut#5216, ocornut#7302, ocornut#7573)

* (Breaking) Renamed ImGuiSelectableFlags_DontClosePopups to ImGuiSelectableFlags_NoAutoClosePopups. (ocornut#1379, ocornut#1468, ocornut#2200, ocornut#4936, ocornut#5216, ocornut#7302, ocornut#7573)

* Obsoleted PushTabStop()/PopTabStop() in favor of using new PushItemFlag()/PopItemFlag() with ImGuiItemFlags_NoTabStop.

* Fixed pvs-studio warning.

* Demo: Property Editor: rearrange code + replace use of bool to proper ImGuiChildFlags.

Amend 46691d1

* Demo: Property Editor: add basic filter.

* Style: close button and collapse/window-menu button hover highlight made rectangular instead of round.

The reason they were round in the first place was to work better with rounded windows/frames.
However since the 4a81424 rework ocornut#6749 we can naturally use a tigher bounding box and it seems to work ok either way.

* Nav, Demo: comments.

* Clipper: added SeekCursorForItem() function, for use when using ImGuiListClipper::Begin(INT_MAX). (ocornut#1311)

Tagging ocornut#3609 just in case we made a mistake introducing a regression (but tests are passing and have been extended).

* TreeNode: Internals: facilitate dissociating item ID from storage ID (useful for 1861)

* Internals: rename recently added TreeNodeIsOpen() -> TreeNodeGetOpen(). (ocornut#7553, ocornut#1131, ocornut#2958, ocornut#2079, ocornut#722)

Amend ac7d6fb

* Backends: SDL3: Update for API changes: SDL_GetClipboardText() string ownership change. (ocornut#7801)

* MultiSelect: WIP range-select (ocornut#1861) (rebased six millions times)

* MultiSelect: Removed SelectableSpacing as I'm not sure it is of use for now (history insert)

* MultiSelect: Added IMGUI_HAS_MULTI_SELECT define. Fixed right-click toggling selection without clearing active id, could lead to MarkItemEdited() asserting. Fixed demo.

* MultiSelect: Demo sharing selection helper code. Fixed static analyzer warnings.

* MultiSelect: Renamed SetNextItemMultiSelectData() to SetNextItemSelectionUserData()

* MultiSelect: Transition to use FocusScope bits merged in master.

Preserve ability to shift+arrow into an item that is part of FocusScope but doesn't carry a selection without breaking selection.

* MultiSelect: Fix for TreeNode following merge of 011d475. Demo: basic test for tree nodes.

* MultiSelect: Fixed CTRL+A not testing focus scope id. Fixed CTRL+A not testing active id. Added demo code.

Comments.

* MultiSelect: Comments. Tweak demo.

* MultiSelect: Fix Selectable() ambiguous return value, clarify need to use IsItemToggledSelection().

* MultiSelect: Fix testing key mods from after the nav request (remove need to hold the mod longer)

* MultiSelect: Temporary fix/work-around for child/popup to not inherit MultiSelectEnabled flag, until we make mulit-select data stackable.

* MultiSelect: Fixed issue with Ctrl+click on TreeNode + amend demo to test drag and drop.

* MultiSelect: Demo: Add a simpler version.

* MultiSelect: Added ImGuiMultiSelectFlags_ClearOnEscape (unsure of best design), expose IsFocused for custom shortcuts.

* MultiSelect: Demo: Added pointer indirection and indent level.

This is to reduce noise for upcoming commits, ahead of adding a loop here.

* MultiSelect: Added ImGuiMultiSelectFlags_ClearOnClickWindowVoid. + Demo: showcase multiple selection scopes in same window.

* MultiSelect: Enter doesn't alter selection (unlike Space).

Fix for changes done in 5606.

* MultiSelect: Shallow tweaks/refactors.

Including moving IsFocused back internally for now.

* MultiSelect: Fixed needing to set RangeSrcPassedBy when not using clipper.

* MultiSelect: made SetNextItemSelectionData() optional to allow disjoint selection (e.g. with a CollapsingHeader between items). Amend demo.

* MultiSelect: Enter can alter selection if current item is not selected.

* MultiSelect: removed DragDropActive/preserve_existing_selection logic which seems unused + comments.

Can't find trace of early prototype for range-select but I couldn't find way to trigger this anymore. May be wrong. Will find out.

* MultiSelect: refactor before introducing persistant state pool and to facilitate adding recursion + debug log calls.

This is mostly the noisy/shallow stuff committed here, to get this out of the way.

* MultiSelect: (Breaking) Rename ImGuiMultiSelectData to ImGuiMultiSelectIO.

* MultiSelect: Demo tweak. Removed multi-scope from Advanced (too messy), made it a seperate mini-demo.

* MultiSelect: Internals rename of IO fields to avoid ambiguity with io/rw concepts + memset constructors, tweaks.

debug

* MultiSelect: (Breaking) Renamed 'RangeSrc -> 'RangeSrcItem', "RangeDst' -> 'RangeDstItem'

This is necessary to have consistent names in upcoming fields (NavIdItem etc.)

* MultiSelect: (Breaking) Renamed 'RangeValue' -> 'RangeSelected' + amend comments.

* MultiSelect: Remove ImGuiMultiSelectFlags_NoUnselect because I currently can't find use for this specific design.

And/or it seem partly broken.

* MultiSelect: Remove the need for using IsItemToggledSelection(). Update comments.

This is the simple version that past our tests. MultiSelectItemFooter() is in need of a cleanup.

* MultiSelect: Tidying up/simpllifying MultiSelectItemFooter().

Intended to be entirely a no-op, merely a transform of source code for simplification. But committing separatey from behavior change in previous change.

* MultiSelect: Clarify and better enforce lifetime of BeginMultiSelect() value.

* MultiSelect: Demo: first-draft of user-side deletion idioms.

(will need support from lib)

* MultiSelect: (Breaking) BeginMultiSelect() doesn't need two last params maintained by users. Moving some storage from user to core. Proper deletion demo.

* MultiSelect: Maintain NavIdSelected for user. Simplify deletion demo.

* MultiSelect: Further simplication of user code to support Deletion.

Provide standard RequestFocusItem storage.

* MultiSelect: Demo: Delete items from menu.

* MultiSelect: Fixed right-click handling in MultiSelectItemFooter() when not focused.

* MultiSelect: Cleanup unused comments/code.

* MultiSelect: (Breaking) Fix + Rename ImGuiMultiSelectFlags_NoMultiSelect to ImGuiMultiSelectFlags_SingleSelect as it seems easier to grasp.

Feature was broken by "Tidying up..." June 30 commit.

* MultiSelect: Comments, tweaks.

+ Alignment to reduce noise on next commit.

* MultiSelect: (Breaking) Use ImGuiSelectionUserData (= ImS64) instead of void* for selection user data.

Less confusing for most users, less casting.

* MultiSelect: move HasSelectionData to ImGuiItemFlags to facilitate copying around in standardized fieds.

Required/motivated to simplify support for ImGuiTreeNodeFlags_NavLeftJumpsBackHere (bc3c0ce) in this branch.

* MultiSelect: Tweak debug log to print decimal+hex values for item data.

Struggled to get standard PRIX64 to work on CI.

* MultiSelect: clear selection when leaving a scope with a nav directional request.

May need to clarify how to depends on actions being performed (e.g. click doesn't).
May become optional?

* MultiSelect: (Breaking) RequestSetRange's parameter are RangeFirstItem...RangeLastItem (which was always ordered unlike RangeSrcItem...RangeDstItme). Removed RangeDstItem. Removed RangeDirection.

* MultiSelect: Demo: rework ExampleSelection names to map better to typical user code + variety of Comments tweaks.

* MultiSelect: Demo: added simpler demo using Clipper. Clarify RangeSrcPassedBy doc.

* MultiSelect: (Breaking) Removed RangeSrcPassedBy in favor of favoring user to call IncludeByIndex(RangeSrcItem) which is easier/simpler to honor.

Especially as recent changes made it required to also update RangeSrcPassedBy after last clipper Step.
Should now be simpler.

* MultiSelect: Demo: rework ExampleSelection with an ExampleSelectionAdapter layer, allowing to share more code accross examples using different storage systems.

Not ideal way to showcase this demo but this is really more flexible.

* MultiSelect: Demo: Remove UserDataToIndex from ExampleSelectionAdapter.

Seems to make a better demo this way.

* MultiSelect: Demo: Make ExampleSelection use ImGuiID. More self-explanatory.

* MultiSelect: Demo: Deletion: Rework ApplyDeletionPreLoop to use adapter + fix PostLoop not using right value of RequestFocusItem.

Recovery made it transparent visually but user side selection would be empty for a frame before recovery.

* MultiSelect: Demo: Deletion: Various renames to clarify. Use adapter and item list in both ApplyDeletion functions.

This also minify the patch for an alternative/wip attmept at redesgining pre/post deletion logic. But turns out current attempt may be easier to grasp.

* Demo: Dual List Box: Added a dual list box (6648)

* MultiSelect: ImGuiMultiSelectIO's field are not used during loop anymore, stripping them out of comments.

* MultiSelect: moved RequestClear output so it'll match request list version better. Use Storage->RangeSrcItem in EndMultiSelect().

* MultiSelect: move shared logic to MultiSelectItemHeader().

No logic change AFAIK but added an indent level in MultiSelectItemHeader(). Logic changes will come in next commit.

* MultiSelect: Added ImGuiMultiSelectFlags_SelectOnClickRelease to allow dragging an unselected item without altering selection + update drag and drop demo.

* Demo: Assets Browser: Added assets browser demo.

* Demo: Assets Browser: store items, sorting, type overlay.

* MultiSelect: removed seemingly unnecessary block in BeginMultiSelect().

- EndIO.RangeSelected always set along with EndIO.RequestSetRange
- Trying to assert for the assignment making a difference when EndIO.RequestSetRange is already set couldn't find a case (tests passing).

* MultiSelect: clarified purpose and use of IsItemToggledSelection(). Added assert. Moved to multi-selection section of imgui.h.

* MultiSelect: added missing call on Shutdown(). Better reuse selection buffer.

* MultiSelect: (Breaking) io contains a ImVector<ImGuiSelectionRequest> list.

* MultiSelect: we don't need to ever write to EndIO.RangeSrcItem as this is not meant to be used.

* MultiSelect: added support for recovery in ErrorCheckEndWindowRecover().

* MultiSelect: use a single ImGuiMultiSelectIO buffer.

+ using local storage var in EndMultiSelect(), should be no-op.

* MultiSelect: simplify clearing ImGuiMultiSelectTempData.

* Demo: Assets Browser: add hit spacing, requierd for box-select patterns.

* MultiSelect: (breaking) renamed ImGuiMultiSelectFlags_ClearOnClickWindowVoid -> ImGuiMultiSelectFlags_ClearOnClickVoid. Added ImGuiMultiSelectFlags_ScopeWindow, ImGuiMultiSelectFlags_ScopeRect.

* MultiSelect: Box-Select: added support for ImGuiMultiSelectFlags_BoxSelect.

(v11)
FIXME: broken on clipping demo.

* MultiSelect: Box-Select: added scroll support.

* MultiSelect: Demo: rework and move selection adapter inside ExampleSelection.

* MultiSelect: added support for nested/stacked BeginMultiSelect().

Mimicking table logic, reusing amortized buffers.

* MultiSelect: remove ImGuiSelectionRequest/ImGuiMultiSelectIO details from public api to reduce confusion + comments.

* MultiSelect: move demo's ExampleSelection to main api as a convenient ImGuiSelectionBasicStorage for basic users.

* MultiSelect: reworked comments in imgui.h now that we have our own section.

* MultiSelect: Demo: Assets Browser: added deletion support. Store ID in selection. Moved QueueDeletion to local var to emphasis that this is a user extension.

* MultiSelect: Demo: Assets Browser: track scrolling target so we can roughly land on hovered item.

It's impossible to do this perfectly without some form of locking on item because as the hovered item X position changes it's easy to drift.

* MultiSelect: Box-Select: Fixed holes when using with clipper (in 1D list.)

Clipper accounts for Selectable() layout oddity as BoxSelect is sensitive to it.
Also tweaked scroll triggering region inward.
Rename ImGuiMultiSelectFlags_NoBoxSelectScroll to ImGuiMultiSelectFlags_BoxSelectNoScroll.
Fixed use with ImGuiMultiSelectFlags_SinglaSelect.

* MultiSelect: Box-Select: Added ImGuiMultiSelectFlags_BoxSelect2d support. Enabled in Asset Browser. Selectable() supports it.

* MultiSelect: Box-Select: Refactor into its own structure, designed for single-instance but closer to being reusable outside Multi-Select.

Kept same member names.

* MultiSelect: Box-Select: Refactor: Renames.

Split into two commits to facilite looking into previous one if needed.

* MultiSelect: Box-Select: Fixed scrolling on high framerates.

* MultiSelect: Box-Select: Further refactor to extra mode code away from multi-select function into box-select funcitons.

* MultiSelect: Fixed ImGuiSelectionBasicStorage::ApplyRequests() incorrectly maintaining selection size on SelectAll.

* MultiSelect: Comments + Assets Browser : Tweak colors.

* MultiSelect: Added ImGuiMultiSelectFlags_NoRangeSelect. Fixed ImGuiMultiSelectFlags_ScopeRect not querying proper window hover.

* MultiSelect: Box-Select: Fixed CTRL+drag from void clearing items.

* MultiSelect: Box-Select: Fixed initial drag from not claiming hovered id, preventing window behind to move for a frame.

* MultiSelect: Fixed ImGuiMultiSelectFlags_SelectOnClickRelease over tree node arrow.

* MultiSelect: (Breaking) merge ImGuiSelectionRequestType_Clear and ImGuiSelectionRequestType_SelectAll into ImGuiSelectionRequestType_SetAll., rename ImGuiSelectionRequest::RangeSelected to Selected.

The reasoning is that it makes it easier/faster to write an adhoc ImGuiMultiSelectIO handler (e.g. trying to apply multi-select to checkboxes)

* MultiSelect: Simplified ImGuiSelectionBasicStorage by using a single SetItemSelected() entry point.

* MultiSelect: Comments + tweaked location for widgets to test ImGuiItemFlags_IsMultiSelect to avoid misleading into thinking doing it before ItemAdd() is necessary.

* MultiSelect: Demo: make various child windows resizable, with synched heights for the dual list box demo.

* MultiSelect: added ImGuiMultiSelectFlags_NoAutoSelect, ImGuiMultiSelectFlags_NoAutoClear features + added Checkbox Demo

Refer to "widgets_multiselect_checkboxes" in imgui_test_suite.

* MultiSelect: Box-Select: fix preventing focus. amend determination of scope_hovered for decorated/non-child windows + avoid stealing NavId. (ocornut#7424)

* MultiSelect: Demo: use Shortcut().

Got rid of suggestion to move Delete signal processing to BeginMultiSelect(), seems unnecessary.

* RangeSelect/MultiSelect: (Breaking) Added current_selection_size to BeginMultiSelect().

Required for shortcut routing so we can e.g. have Escape be used to clear selection THEN to exit child window.

* MultiSelect: Box-Select: minor refactor, tidying up.

* MultiSelect: Box-Select: when dragging from void, first hit item sets NavId by simulating a press, so navigation can resume from that spot.

* MultiSelect: added GetMultiSelectState() + store LastSelectionSize as provided by user, convenient for quick debugging and testing.

* MultiSelect: Box-Select: fixed "when dragging from void" implementation messing with calling BeginMultiSelect() without a selection size.

* MultiSelect: (breaking) renamed ImGuiSelectionBasicStorage::AdapterData to UserData.

* MultiSelect: Box-Select: fixes for checkboxes support. Comments.

* MultiSelect: (breaking) renamed ImGuiMultiSelectFlags_BoxSelect -> ImGuiMultiSelectFlags_BoxSelect1d, ImGuiMultiSelectFlags_BoxSelect2d -> ImGuiMultiSelectFlags_BoxSelect.

ImGuiMultiSelectFlags_BoxSelect1d being an optimization it is the optional flag.

* MultiSelect: mark parent child window as navigable into, with highlight. Assume user will always submit interactive items.

* MultiSelect: (breaking) Added 'items_count' parameter to BeginMultiSelect(). Will enable extra features, and remove equivalent param from ImGuiSelectionBasicStorage::ApplyRequests(.

* MultiSelect: added ImGuiSelectionBasicStorage::GetStorageIdFromIndex() indirection to be easier on the reader.

Tempting to make it a virtual.

* MultiSelect: fixed ImGuiSelectionBasicStorage::Swap() helper.

* MultiSelect: added ImGuiSelectionExternalStorage helper. Simplify bool demo.

* MultiSelect: comments, header tweaks., simplication (some of it on wiki).

* MultiSelect: ImGuiSelectionBasicStorage: added GetNextSelectedItem() to abstract selection storage from user. Amend Assets Browser demo to handle drag and drop correctly.

* MultiSelect: ImGuiSelectionBasicStorage: rework to accept massive selections requests without flinching.

Batch modification + storage only keeps selected items.

* MultiSelect: ImGuiSelectionBasicStorage: simplify by removing compacting code (compacting may be opt-in?).

GetNextSelectedItem() wrapper gives us more flexibility to work on this kind of stuff now.

* MultiSelect: ImGuiSelectionBasicStorage: move function bodies to cpp file.

+ make ImGuiStorage::BuildSortByKey() less affected by msvc debug mode.

* Demo: Assets Browser: added a way to disable sorting and hide sorting options.

This is mostly designed to showcase that on very large sets (e.g. 1 million) most of the time is likely spent on sorting.

* MultiSelect: ImGuiSelectionBasicStorage: (breaking) rework GetNextSelectedItem() api to avoid ambiguity/failure when user uses a zero id.

* MultiSelect: provide RangeDirection to allow selection handler to handler backward shift+click.

* MultiSelect: ImGuiSelectionBasicStorage: added PreserveOrder, maintain implicit order data in storage.

Little tested but provided for completeness.

* MultiSelect: (breaking) renamed ImGuiMultiSelectFlags_BoxSelect -> ImGuiMultiSelectFlags_BoxSelect2d. Which include not assuming one flag imply the other.

Amend 2024/05/31 commit.

* MultiSelect: Shift+Tab doesn't enable Shift select on landing item.

* MultiSelect: added ImGuiMultiSelectFlags_NoAutoClearOnReselect + tweak flags comments. (ocornut#7424)

* MultiSelect: minor tidying up.

Checkbox() was reworked in master effectively fixing render clipping when culled by BoxSelect2d's UnclipMode.

* MultiSelect: added courtesy ImGuiMultiSelectFlags_NavWrapX flag so we can demo this until a nav api is designed.

* MultiSelect: Box-Select: uses SetActiveIdUsingAllKeyboardKeys() to avoid nav interference, much like most drag operations.

* MultiSelect: Box-Select: handle Esc to disable box-select.

This avoid remove a one-frame delay when finishing box-select, where Esc wouldn't be routed to selection but to child.

* MultiSelect: ImGuiSelectionBasicStorage: optimized for smaller insertion amounts in larger sets + fix caling batch select with same value.

* MultiSelect: Better document how TreeNode() is not trivially usable yet.

Will revert when the time is right.

* MultiSelect: added Changelog for the feature. Removed IMGUI_HAS_MULTI_SELECT.

* Demo: moved ExampleTreeNode, ExampleMemberInfo above in the demo file. Tidying up index.

+ change ExampleTreeNode::UID from ImGuiID to int to not suggest that the user ID needs to be of a certain type

* Demo: moved some fields inside a struct.

* Demo: moved menu bar code to its own function.

* MultiSelect: using ImGuiMultiSelectFlags_NoRangeSelect ensure never having to interpolate between two ImGuiSelectionUserData.

* Inputs: added SetItemKeyOwner(ImGuiKey key) in public API. (ocornut#456, ocornut#2637, ocornut#2620, ocornut#2891, ocornut#3370, ocornut#3724, ocornut#4828, ocornut#5108, ocornut#5242, ocornut#5641)

* Backends: SDL3: Update for API changes: SDL_GetGamepads() memory ownership change. (ocornut#7807)

* TabBar, Style: added style option for the size of the Tab-Bar Overline (ocornut#7804)

Amend 21bda2e.

* Added a comment hinting at how to set IMGUI_API for shared librairies on e.g. Linux, macOS (ocornut#7806)

* Demo: rework Property Editor.

* Nav: fixed c licking window decorations (e.g. resize borders) from losing focused item when within a child window using ImGuiChildFlags_NavFlattened.

In essence, using ImGuiFocusRequestFlags_RestoreFocusedChild here is a way to reduce changes caused by FocusWindow(), but it could be done more neatly.
See amended "nav_flattened" test.

* Demo: Property Editor: using ImGuiChildFlags_NavFlattened now that a bug is fixed. Fixed static analyzer.

* Backends: OpenGL3: Fixed unsupported option warning with apple clang (ocornut#7810)

* Internals, TreeNode: indent all render block into its own scope (aim is to add a is_visible test there later)

* Internals, TreeNode, Selectable: tweak span_all_columns paths for clarity.

* CollapsingHeader: left-side outer extend matches right-side one (moved left by one pixel)

Amend c3a348a

* Debug Log: fixed incorrect checkbox layout when partially clipped., doesn't parse 64-bits hex value as ImGuiID lookups.

* Groups, Tables: fixed EndGroup() failing to correctly capture current table occupied size. (ocornut#7543)

See "layout_group_endtable" test.

* MultiSelect: sequential SetRange merging not generally handled by box-select path, useful for others.

* MultiSelect: add internal MultiSelectAddSetAll() helper.

* MultiSelect: fixed an issue caused by previous commit.

Amend a285835. Breaks box-select.

---------

Co-authored-by: ocornut <omarcornut@gmail.com>
Co-authored-by: cfillion <cfillion@users.noreply.github.com>
Co-authored-by: Gary Geng <garygengxiao@gmail.com>
Co-authored-by: Martin Ejdestig <marejde@gmail.com>
Co-authored-by: Kevin Coghlan <mail@kevincoghlan.com>
Co-authored-by: Connor Clark <cjamcl@gmail.com>
Co-authored-by: Max Ortner <maxortner01@gmail.com>
Co-authored-by: Hugues Evrard <hevrard@users.noreply.github.com>
Co-authored-by: Aemony <10578344+Aemony@users.noreply.github.com>
Co-authored-by: Yan Pujante <ypujante@proton.me>
Co-authored-by: Cyao <94928179+cheyao@users.noreply.github.com>
Co-authored-by: wermi <32251376+wermipls@users.noreply.github.com>
Co-authored-by: Thomas Stehle <th.stehle@icloud.com>
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

7 participants