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

Column headers #513

Closed
itamago opened this issue Jan 29, 2016 · 23 comments
Closed

Column headers #513

itamago opened this issue Jan 29, 2016 · 23 comments

Comments

@itamago
Copy link

itamago commented Jan 29, 2016

Hello,

In case you are creating tables with lot of columns, here is a short code snippet to quickly manage the column headers :

struct ColumnHeader
{
    const char* label;
    float size;
};

ColumnHeader headers[] =
    {
        { "Idx", 50 },
        { "Name", 500 },
        { "RT", 50 },
        { "Depth", 50 },
        { "Full", 50 },
        { "ClearColor", 50 },
        { "Width", 250 },
        { "Height", 250 },
        { "Filter", 250 },
        { "WrapU", 250 },
        { "WrapV", 250 },
        { "Flip", 50 },
        { "Filename", 450 }
    };

ImGui::Columns(IM_ARRAYSIZE(headers), "TableTextureColumns", true);
ImGui::Separator();
float offset = 0.0f;
for(ColumnHeader & header : headers)
{
    ImGui::Text(header.label);
    ImGui::SetColumnOffset(-1, offset);
    offset += header.size;
    ImGui::NextColumn();
}
ImGui::Separator();

// and then iterate over the rows of your table...

I'm wondering if there is a simple way to make the headers "fixed", like in Excel when the top row is fixed ?
Because you obviously want to see the headers while scrolling in your table.

Thx

@itamago
Copy link
Author

itamago commented Jan 29, 2016

A more elaborate code snippet for headers.
If you put a negative column-width, the width is calculated according to the column's label.
There is a flag (makeColumsWidthFixed) to set column widths every frames or only the first time.

// Header
struct ColumnHeader
{
    const char* label;
    float size;
};

ColumnHeader headers[] =
    {
        { "Idx",        -1 },
        { "Name",       500 },
        { "RT",         -1 },
        { "Depth",      -1 },
        { "Full",       -1 },
        { "ClearColor", -1 },
        { "Width",      150 },
        { "Height",     150 },
        { "Filter",     150 },
        { "WrapU",      150 },
        { "WrapV",      150 },
        { "Flip",       -1 },
        { "Filename",   450 }
    };

ImGui::Columns(EASE_ARRAYSIZE(headers), "WinTextureColumns", true);
ImGui::Separator();
float offset = 0.0f;
ImGuiStyle & style  = ImGui::GetStyle();

const bool makeColumsWidthFixed = false;
static bool s_firstTime = true;

for(ColumnHeader & header : headers)
{
    if(s_firstTime || makeColumsWidthFixed)
    {
        ImGui::SetColumnOffset(-1, offset);
        if(header.size >= 0)
        {
            offset += header.size;
        }
        else
        {
            ImVec2 textsize = ImGui::CalcTextSize(header.label, NULL, true);
            offset += (textsize.x + 2 * style.ItemSpacing.x);
        }
    }
    ImGui::Text(header.label);
    ImGui::NextColumn();
}
ImGui::Separator();

if(s_firstTime)
    s_firstTime = false;

@itamago
Copy link
Author

itamago commented Jan 29, 2016

Ok, after 1 coffee (I'm sick today...), here is a cleaner helper for column headers.

Considering you have two user files imgui_user.h and imgui_user.inl, here is the code for the helper :

In imgui_user.h :

namespace ImGui
{
    // ColumnHeader
    struct ColumnHeader
    {
        const char* label = NULL;           // Label of the header
              float size  = -1.0f;          // Negative value will calculate the size to fit label
    };

    // Draw column header
    IMGUI_API void ColumnHeaders(const char* columnsId, ColumnHeader* headers, int count, bool setWidths, bool border=true, bool separator=true);

} // namespace ImGui

In imgui_user.inl :

namespace ImGui
{

    // Draw column header
    void ColumnHeaders(const char* columnsId, ColumnHeader* headers, int count, bool setWidths, bool border, bool separator)
    {
        ImGui::Columns(count, columnsId, border);

        if(separator)
            ImGui::Separator();

        float offset = 0.0f;
        ImGuiStyle & style  = ImGui::GetStyle();

        for(int i=0; i < count; i++)
        {
            const ColumnHeader & header = headers[i];
            if(setWidths)
            {
                ImGui::SetColumnOffset(-1, offset);
                if(header.size >= 0)
                {
                    offset += header.size;
                }
                else
                {
                    ImVec2 textsize = ImGui::CalcTextSize(header.label, NULL, true);
                    offset += (textsize.x + 2 * style.ItemSpacing.x);
                }
            }
            ImGui::Text(header.label);
            ImGui::NextColumn();
        }

        if(separator)
            ImGui::Separator();
    }

} // namespace ImGui

And the code you put in your GUI :

    // Column headers
    const bool makeColumsWidthFixed = false;
    static bool s_firstTime = true;

    ImGui::ColumnHeader headers[] =
        {
            { "Idx",        -1 },
            { "Name",       500 },
            { "RT",         -1 },
            { "Depth",      -1 },
            { "Full",       -1 },
            { "ClearColor", -1 },
            { "Width",      150 },
            { "Height",     150 },
            { "Filter",     150 },
            { "WrapU",      150 },
            { "WrapV",      150 },
            { "Flip",       -1 },
            { "Filename",   450 }
        };

    ImGui::ColumnHeaders("WinTextureColumns", headers, EASE_ARRAYSIZE(headers), s_firstTime || makeColumsWidthFixed, true, true);

    if(s_firstTime)
        s_firstTime = false;

Ok, the "s_firstTime" flag could be handled internally the same way it is done for window's sizing... But I'm sick today...

@itamago
Copy link
Author

itamago commented Jan 29, 2016

I'm still wondering how to make the column-headers fixed (like a top row in excel).
Anyone has an idea ?

@ocornut
Copy link
Owner

ocornut commented Jan 29, 2016

Thanks. We may want to use that for inspiration as the columns API develops.
Linking to #125 where older columns discussions happened.
My feeling is that we should introduce full-featured BeginColumns() / EndColumns() - (old Api Columns() can stay) so it is good to identify the different needs it may have and how those parameters would fit.

To answer your question, it can be done by duplicating the column set outside and inside a child window, but the columns offset needs to be synchronized across two sets. It's possible right now but a bit messy - figuring out minor offsetting issues due to child window padding and the presence of a scrollbar. That's the sort of thing that once we figure out we should include as part of a helper, maybe BeginColumns()/EndColumns(), so it's good to experiment with it.

Some other consideration: (some of them are discussed in #125)

  • clicking on columns header to provide a sort order to the app (optional)
  • moving / re-ordering columns headers (optional)
  • allowing the user to create finer interaction with columns header, perhaps add a context menu, might lead to an api more consistent with other ImGui where headers are declared one by one instead of packed into a table.
  • allowing user to add/remove columns headers (optional - aka for storage columns may need to be identified by name and not by indices, with a single hashing cache when starting the columns set).

We don't need all those features ready but I want to be confident that we can tackle all of them properly before introducing a new BeginColumns() api. So any research in those area is useful.

PS: You don't have to user imgui_user files anyway since you can include imgui_internal.h and have access to the most of the no-warantee-given innards there.

@itamago
Copy link
Author

itamago commented Jan 29, 2016

Ok, I followed your advice, and it works pretty well when syncing both set of columns.

imgui_user.h :

namespace ImGui
{

    // ColumnHeader
    struct ColumnHeader
    {
        const char* label      = NULL;          // Label of the header
              float size       = -1.0f;         // Negative value will calculate the size to fit label
        // Internal
              float syncOffset = -1.0f;         // Internal offset used for sync purpose
    };

    // Draw column headers
    IMGUI_API void ColumnHeaders(const char* columnsId, ColumnHeader* headers, int count, bool border=true);

    // Synchronize with column headers
    IMGUI_API void BeginColumnHeadersSync(const char* columnsId, ColumnHeader* headers, int count, bool border=true);
    IMGUI_API void EndColumnHeadersSync(ColumnHeader* headers, int count);

} // namespace ImGui

imgui_user.inl :

    // Draw column headers
    void ColumnHeaders(const char* columnsId, ColumnHeader* headers, int count, bool border)
    {
        if(count<=0)
            return;

        ImGuiStyle & style = ImGui::GetStyle();
        const ImVec2 firstTextSize = ImGui::CalcTextSize(headers[0].label, NULL, true);

        ImGui::BeginChild(columnsId, ImVec2(0,firstTextSize.y + 2 * style.ItemSpacing.y), true);


        char str_id[256];
        ImFormatString(str_id, IM_ARRAYSIZE(str_id), "col_%s", columnsId);

        ImGui::Columns(count, str_id, border);

        float offset = 0.0f;

        for(int i=0; i < count; i++)
        {
            ColumnHeader & header = headers[i];
            printf("SetColumnOffset %d -> %d\n", i, int(header.syncOffset));
            if(header.syncOffset < 0.0f)
            {
                ImGui::SetColumnOffset(i, offset);
                if(header.size >= 0)
                {
                    offset += header.size;
                }
                else
                {
                    const ImVec2 textsize = ImGui::CalcTextSize(header.label, NULL, true);
                    offset += (textsize.x + 2 * style.ItemSpacing.x);
                }
            }
            else
            {
                ImGui::SetColumnOffset(i, header.syncOffset);
            }
            header.syncOffset = ImGui::GetColumnOffset(i);
            printf("Header %d -> %d\n", i, int(header.syncOffset));
            ImGui::Text(header.label);
            ImGui::NextColumn();
        }

        ImGui::Columns(1);
        ImGui::EndChild();
    }

    // Synchronize with column headers
    void BeginColumnHeadersSync(const char* columnsId, ColumnHeader* headers, int count, bool border)
    {
        if(count<=0)
            return;

        ImGui::BeginChild(columnsId, ImVec2(0,0), true);
        ImGui::Columns(count, columnsId, border);

        float offset = 0.0f;
        ImGuiStyle & style  = ImGui::GetStyle();

        for(int i=0; i < count; i++)
        {
            ColumnHeader & header = headers[i];
            ImGui::SetColumnOffset(i, header.syncOffset);
            header.syncOffset = ImGui::GetColumnOffset(i);
            printf("Content %d -> %d\n", i, int(header.syncOffset));
        }
    }

    void EndColumnHeadersSync(ColumnHeader* headers, int count)
    {
        if(count<=0)
            return;

        ImGui::Columns(1);
        ImGui::EndChild();
    }

And the usage becomes a lot easier :

    // Header definition must be STATIC in order to keep internal data alive. Else, columns will not be dragable.
    static ImGui::ColumnHeader headers[] =
        {
            { "Idx",        -1 },
            { "Name",       500 },
            { "RT",         -1 },
            { "Depth",      -1 },
            { "Full",       -1 },
            { "ClearColor", -1 },
            { "Width",      150 },
            { "Height",     150 },
            { "Filter",     150 },
            { "WrapU",      150 },
            { "WrapV",      150 },
            { "Flip",       -1 },
            { "Filename",   450 }
        };

    ImGui::ColumnHeaders("WinTextureHeader", headers, IM_ARRAYSIZE(headers), true);

    // Table content
    ImGui::BeginColumnHeadersSync("WinTextureContent", headers, IM_ARRAYSIZE(headers), true);

    // DRAW ALL YOUR ROWS HERE

    ImGui::EndColumnHeadersSync(headers, EASE_ARRAYSIZE(headers));

Here is a capture of a test :
screen shot 2016-01-29 at 14 18 29

The only 2 things I still dislike is :

  • When syncing top Columns with bottom ones, there is no lag. But when syncing from bottom ones to top ones, there is one frame lag.
  • When you resize the window, the columns are not resized anymore because of the sync mechanism.
    But these artefacts are acceptable.

Ok.

Next, I would like to handle the double-click on a column-bar in order to resize the column to come back to its original size (same than Excel).
Any ideas about that ? (I'm not very familiar with ImGUI inputs... sorry)

@ocornut
Copy link
Owner

ocornut commented Jan 29, 2016

When syncing top Columns with bottom ones, there is no lag. But when syncing from bottom ones to top ones, there is one frame lag.

That fix is definitively desirable. We should definitively find a way to fix that. However, when using headers it may also be acceptable to restrict resizing to the headers section only and then it's easy to solve.

When you resize the window, the columns are not resized anymore because of the sync mechanism. But these artefacts are acceptable.

That's also something that could be considered as part of the "how do we express the column width". Your current system has width values (or -1) only, perhaps columns can be marked as "use remaining space" or have a finer way to express the constraints. Again this needs a little research. Note that I currently store width as % of the total width to handle this sort of thing in the basic.

Next, I would like to handle the double-click on a column-bar in order to resize the column to come back to its original size (same than Excel). Any ideas about that ? (I'm not very familiar with ImGUI inputs... sorry)

That interaction is currently handled in Columns()

            bool hovered, held;
            ButtonBehavior(column_rect, column_id, &hovered, &held, true);
            if (hovered || held)
                g.MouseCursor = ImGuiMouseCursor_ResizeEW;

            // Draw before resize so our items positioning are in sync with the line being drawn
            const ImU32 col = GetColorU32(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column);
            const float xi = (float)(int)x;
            window->DrawList->AddLine(ImVec2(xi, y1+1.0f), ImVec2(xi, y2), col);

            if (held)
            {
                if (g.ActiveIdIsJustActivated)
                    g.ActiveClickDeltaToCenter.x = x - g.IO.MousePos.x;

                x = GetDraggedColumnOffset(i);
                SetColumnOffset(i, x);
            }

This ties with my earlier comment "allowing the user to create finer interaction with columns header, perhaps add a context menu, might lead to an api more consistent with other ImGui where headers are declared one by one instead of packed into a table.". We either need to code in this feature in that code, either expose the interaction somehow. If we have an api were columns are declared separately, it'd be easier to allow for the user to handle custom interactions.

Lots of open problems, thanks for trying those things. It is worth pushing those problems for now, and then we can design better api that would handle all/most of them properly.

Minor tips:

  • call AlignFirstTextHeightToWidgets() helper before your text field to vertically align them (and/or remove padding on the input field). Normally you'd have to do it once per line (on the Idx field) but the line height doesn't spread across columns (also an interesting thing to consider for later).
  • you can use ImGuiListClipper helper to "seek" directly to the visible portion of your list, reducing the CPU cost to a fraction if you have thousands of items.

@itamago
Copy link
Author

itamago commented Jan 29, 2016

Disabling the sync from bottom to top Columns solves both issues : no more lag (obviously), and when resizing the window all the columns follow the sizes of the top ones.
So, everything is quite good.
But, there is a new behaviour not really appealing : the bottom columns are still draggable, and when I drag one of them it takes back its place when drag-event ends (same place than the top-column).

I'll look at a way to disable dragging for bottom-columns only.

Thanks for the AlignFirstTextHeightToWidgets() tip ! I didn't see the misalignment at all, too much focused on the columns !
I had to put this call before every text fields of a single line to make them Venter-aligned, as if the NextColumn() is resetting the context.

Great that you gave me the tip for clipping, because that would have been my next question :)

@itamago
Copy link
Author

itamago commented Jan 29, 2016

Mmmh... The clipper has side effects : the first line is not correctly detected, and when I scroll by dragging the scrollbar it is flickering. I'll look at what is wrong with it..

screen shot 2016-01-29 at 18 32 26

Edit : I found that issue #512 may be related.

@ocornut
Copy link
Owner

ocornut commented Jan 29, 2016

You probably aren't passing the right height for your items. There is a helper that gives you FontSize + ItemSpacing.y + FramePadding.y*2

If you aren't sure of your height try seeking position +1 manually (using SetCursorPosY()) when eg. io.KeyCtrl is held for an easy comparison.

On 2016/01/29, at 17:27, Pacôme Danhiez [email protected] wrote:

Mmmh... The clipper has side effects : the first line is not correctly detected, and when I scroll by dragging the scrollbar it is flickering. I'll look at what is wrong with it..


Reply to this email directly or view it on GitHub.

@itamago
Copy link
Author

itamago commented Jan 30, 2016

Here are the sources from yesterday evening (yes, I discovered Gist... ah ah) :

imgui_column_headers.h : https://gist.github.com/itamago/27f09c429d625a0d31ec
imgui_column_headers.cpp : https://gist.github.com/itamago/f297dee5788c4d9b9441
imgui_column_headers_usage.cpp : https://gist.github.com/itamago/7b305ee9aaf31843b8d1

Works quite well.

In the following capture, you will recognise the wip color-picker :
screen shot 2016-01-30 at 08 43 59

Having ideas lot more clear than yesterday (no more fever), I have some questions which may be totally newbie ones...

  • How do you make these widgets horizontal-centered in a column : CheckBox, ColorButton, Text ?
  • How do you left-align the text of a button ? (It seems pretty simple to modify the Button and ButtonEx functions by forwarding a ImGuiAlign flag which will be used in RenderTextClipped, so I guess there is another reason it's not done)
  • I love the wip-colorPicker ! Do you plan to make it resizable ?
  • What is the best way to handle multiple font-sizes ? For instance, I would like to reduce the font-size in Comboboxes, is it possible to apply a font-scale or something like that ?

Sorry if they are newbie question, and I would totally understand that I should more carefully RTFM, but I'm still sick lol :)

@ocornut
Copy link
Owner

ocornut commented Jan 30, 2016

Thanks. We should aim to make all this code invisible eventually.

I am wondering if the performances are holding up with so much columns switches. In particular NextColumn() does a PopClipRect()/PushColumnClipRect() which will always end up in a merged command, I think with recent changes to ImDrawList I should be able to remove those calls and only do them once at the begining/end of the set. Same for PushItemWidth which ideally should be preserved on a per-column basis. It's all fairly small/fast stuff but it may add up when you are drawing thousands of calls. Hope to remove those 4 calls from NextColumns() at least.

Typically I wouldn't even use so many columns, note how most of your elements don't really need to be resized. I'm always a little concerned when people try to push ImGui in a direction of trying to mimic well known UI systems and losing on the usage simplicity benefits of ImGui.. You can't turn a blind eye on the core design/benefits/limitations of ImGui and expect mimic to happen. You may end up disappointed!

I am not sure I want to turn ImGui into pretty-face options because that would defeat lots of its benefits. And frankly I don't have sufficient bandwidth to handle it, every micro visual decision has side-effects on code and performance (if I had the time I would consider finding the best spot between those two opposites).

How do you make these widgets horizontal-centered in a column : CheckBox, ColorButton, Text ?

You can't, or you set the position yourself.

How do you left-align the text of a button ? (It seems pretty simple to modify the Button and ButtonEx functions by forwarding a ImGuiAlign flag which will be used in RenderTextClipped, so I guess there is another reason it's not done)

You can't, and yes it'd be pretty simple to change. Probably best set within the Style?
Adding the flag to ButtonEx() would also work but maybe give too much importance to that feature.

I love the wip-colorPicker ! Do you plan to make it resizable ?

I plan to try to finish it and get it working first, I haven't figured out how to parametrize it yet.

What is the best way to handle multiple font-sizes ? For instance, I would like to reduce the font-size in Comboboxes, is it possible to apply a font-scale or something like that ?

There is a font scale but the best way is to bake a smaller font and call PushFont.

@itamago
Copy link
Author

itamago commented Jan 30, 2016

You're right, I need only 4 columns (and 2 resizable only).
I created so much columns to benchmark the API, and ImGui is pretty fast :)

Thanks for your advices, I will implement that tomorrow !

@itamago
Copy link
Author

itamago commented Jan 31, 2016

I did a test by reducing from 13 columns to only 4. The widgets were the same, and I kept row-clipping disabled in order to maximise the number of vertices.

The gain is negligible :

  • 13 columns => 65920 vertices / 237117 indices / 79039 triangles
  • 4 columns => 64676 vertices / 235191 indices / 78397 triangles

It means that Columns have a very low overhead, that's great :)

@itamago
Copy link
Author

itamago commented Jan 31, 2016

Updated source code for column-headers, making them more configurable and easier to manage :

  • label : pretty obvious...
  • size : if negative, the size will match the label's one
  • sizeMIN : minimum acceptable size (and if negative will match the label's size)
  • allowResize : whether the column is resizable.

imgui_column_headers.h : https://gist.github.com/itamago/27f09c429d625a0d31ec
imgui_column_headers.cpp : https://gist.github.com/itamago/f297dee5788c4d9b9441
imgui_column_headers_usage.cpp : https://gist.github.com/itamago/7b305ee9aaf31843b8d1

@itamago
Copy link
Author

itamago commented Apr 14, 2016

Nothing new on this topic, so I close it.

@itamago itamago closed this as completed Apr 14, 2016
@ocornut
Copy link
Owner

ocornut commented Apr 14, 2016

Lots of ideas to filter and process. We still need official columns headers, etc. I'd rather keep topics open when they talk about stuff that I intend to do!

@r-lyeh-archived
Copy link

Hey there, simplified header-only snippet because I wanted it shorter and more ImGui styled.
Thank you very much to both of you :)

/*  // [src] https://github.com/ocornut/imgui/issues/513

    // Usage:
    static const char *headers[] = {
        "Index", "Color", "Flip?", "Filename"
    };
    static float widths[ IM_ARRAYSIZE(headers) ] = {}; 
    if( ImGui::BeginTable("WinTextureContent", headers, widths, IM_ARRAYSIZE(headers)) ) {
        // Draw as many rows as needed
        for( int i = 0; i < 10; ++i ) {
            ImGui::Text("%d", i);                              ImGui::NextColumn();
            ImGui::ColorButton( ImVec4(0.5f,0.2f,i*0.3f,1.f)); ImGui::NextColumn();
            ImGui::Text("%s", i % 2 ? "yes" : "no");           ImGui::NextColumn();
            ImGui::Text(__FILE__);                             ImGui::NextColumn();
        }
        ImGui::EndTable();
    }
*/

// .h
namespace ImGui {
IMGUI_API int  BeginTable(const char* columnsId, const char** headers, float *widths, int count, bool border=true);
IMGUI_API void EndTable();
}

// .cpp
namespace ImGui {
static inline IMGUI_API
int BeginTable(const char* columnsId, const char** headers, float* widths, int count, bool draw_border)
{
    if(count<=0)
        return 0;

    // Draw column headers
    ImGuiStyle & style = ImGui::GetStyle();
    const ImVec2 firstTextSize = ImGui::CalcTextSize(headers[0], NULL, true);

    ImGui::BeginChild(columnsId, ImVec2(0,firstTextSize.y + 2 * style.ItemSpacing.y), true);

    char str_id[256];
    sprintf(str_id, "tbl0_%s", columnsId);
    ImGui::Columns(count, str_id, draw_border);

    float offset = 0.0f;
    for(int i=0; i < count; i++)
    {
        ImGui::SetColumnOffset(i, offset);

        if(widths[i] <= 0)
        {
            const ImVec2 textsize = ImGui::CalcTextSize(headers[i], NULL, true);
            const float colSizeX = (textsize.x + 2 * style.ItemSpacing.x);
            widths[i] = colSizeX + 1;
        }

        if(i < (count-1))
        {
            float curOffset = offset;
            offset = ImGui::GetColumnOffset(i+1);
            widths[i] = offset - curOffset + 1;
        }

        ImGui::Text(headers[i]);
        ImGui::NextColumn();
    }

    ImGui::Columns(1);
    ImGui::EndChild();

    // Draw body
    str_id[3] = '1';
    columnsId = str_id;

    ImGui::BeginChild(columnsId, ImVec2(0,0), true);
    ImGui::Columns(count, columnsId, draw_border);

    offset = 0.0f;
    for(int i=0; i < count; i++)
    {
        ImGui::SetColumnOffset(i, offset);
        offset += widths[i] - 1;
    }

    return 1;
}

static inline IMGUI_API
void EndTable()
{
    ImGui::Columns(1);
    ImGui::EndChild();
}

}

@v71
Copy link

v71 commented May 23, 2017

Hello, there is a severe bug when the window hosting the control is resized, the columns lose spacing and its not possibile to reset to their original size.

@ocornut
Copy link
Owner

ocornut commented May 23, 2017

@v71

Hello, there is a severe bug when the window hosting the control is resized, the columns lose spacing and its not possibile to reset to their original size.

With which code? Please provide a repro.

@v71
Copy link

v71 commented May 23, 2017

With the code from r-lyeh , i basically copy pasted into a plain window and it showed the problem as soon as i resized the window, it takes 30 seconds to reproduce, i do not have a gif encoder in this computer right now.

@CallumDev
Copy link

This code doesn't seem to work with latest ImGUI. In the case of the header-only snippet I can use ImGui::BeginColumns(str_id,count,ImGuiColumnsFlags_NoPreserveWidths) but that keeps it to header-only resizing.

@ocornut
Copy link
Owner

ocornut commented Aug 27, 2020

Hello @itamago and all,
As the official Tables API is looming in, I'm closing this old topic about recreating headers with the Columns API.
Thanks for the idea and suggestion discussed here :)

@ocornut ocornut closed this as completed Aug 27, 2020
ocornut added a commit that referenced this issue Nov 18, 2020
…ColumnFlags_*. (#125, #513, #913, #1204, #1444, #2142, #2707)

Affected: ImGuiColumnsFlags_None, ImGuiColumnsFlags_NoBorder, ImGuiColumnsFlags_NoResize, ImGuiColumnsFlags_NoPreserveWidths, ImGuiColumnsFlags_NoForceWithinWindow, ImGuiColumnsFlags_GrowParentContentsSize. Added redirection enums. Did not add redirection type.
@ocornut
Copy link
Owner

ocornut commented Dec 8, 2020

Tables API now merged in master.

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

5 participants