A sortable & filterable table widget

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
User avatar
mickael9
Fast Inserter
Fast Inserter
Posts: 112
Joined: Mon Mar 14, 2016 4:04 am
Contact:

A sortable & filterable table widget

Post by mickael9 »

I just read this topic about the need to get the translated text as needed to the player for sorting & filtering purposes. I think this use case could be covered by a new special table widget with client-side-only filtering and sorting abilities.

Proposal:

The client code filters and sorts rows without their order/visibility ever being part of the game state (like the scrollbar state).
Each widget in the table still has an unique ID and all, but from the mod/game state perspective, it's like all the items are always visible and in their original order. Only the current search filter and sorting information is saved to the game state.

In addition, each top-level (cell) widget inserted in such a table has a new data property with a type of dictionary string -> (number | boolean | LocalisedString)
For each row, the data is merged from all the top-level widgets in that row (duplicate keys can raise an error or just be ignored, it doesn't really matter) and the merged data is used for filtering & sorting that row. LocalisedString values are of course resolved beforehand.

Here is an example of how that would work for, say displaying a table of all items in the game:

Code: Select all

local table_widget = gui.add{type = 'sorted-table', name = 'my-sorted-table', colspan = 3}

for name, proto in pairs(game.item_prototypes) do
    table_widget.add{
        type = 'sprite-button',
        name = 'icon-' .. name,
        sprite = 'item/' .. name,
        data = {
            stack_size = proto.stack_size,
            hidden = proto.has_flag('hidden'),
            subgroup = proto.subgroup.name,
        },
    }

    table_widget.add{
        type = 'label',
        name = 'name-' .. name,
        caption = proto.localised_name,
        data = {
            name = proto.localised_name,
        },
    }

    table_widget.add{
        type = 'label',
        name = 'description-' .. name,
        caption = proto.localised_description,
    }
end
All sorts of filtering can be done:

Code: Select all

table_widget.filters = {
    -- 'name' starts with 'x' OR 'name' contains 'y' (Lua Regexps)
    {
        { name = 'name', value = '^x' },
        { name = 'name', value = 'y' },
    },
    -- AND stack_size > 1
    {
        { name = 'stack_size', operator = '>', value = 1 },
    },
    -- AND not 'hidden'
    {
        { name = 'hidden', value = false },
    },
}
At this point, all rows that don't match those filters are hidden.

And for sorting:

Code: Select all

table_widget.sort = {
    { name = 'subgroup' },               -- first sort rows by ascending value of 'subgroup'
    { name = 'name', reversed = true },  -- then by descending 'name' value for equal values of 'subgroup'
}

sparr
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Fri Feb 14, 2014 5:52 pm
Contact:

Re: A sortable & filterable table widget

Post by sparr »

Bump because this is a great prior suggestion similar to my viewtopic.php?f=28&t=59296

Post Reply

Return to “Modding interface requests”