airstruck / luigi

Lovely User Interfaces for Game Inventors
MIT License
113 stars 23 forks source link

widget : table/array/grid/... #50

Open tst2005 opened 7 years ago

tst2005 commented 7 years ago

Hello,

Is it planned to have a kind of table/grid widget with luigi ?

Something like :

Is someone already tried to do that ?

Regards,

airstruck commented 7 years ago

Hello! No grid widget is planned, but the LoveFrames grid example would look something like this for Luigi:

local Layout = require 'luigi.layout'

local grid = { flow = 'y' }
local id = 1

for i = 1, 5 do
    local row = { flow = 'x' }
    grid[#grid + 1] = row
    for n = 1, 5 do
        row[#row + 1] = { type = 'button', text = id, height = false }
        id = id + 1
    end
end

local layout = Layout(grid)
layout:show()

Does that work for you?

tst2005 commented 7 years ago

Hello,

At first, thanks for your answer! I tested it and it runs! but it's only the beginning ...

I'm trying to show an existing content : a matrix or a sheet. (my final goal is also allowing editing content)

I changed your sample to create a grid that don't have static text but dynamic text (binded on an external data)


local Layout = require 'luigi.layout'

local function new_grid_from_matrix(matrix)
    -- make a text proxy
    local textproxy = function(matrix, x, y)
        return setmetatable({}, {__tostring=function(_self) return matrix[y][x] end})
    end

    local max_x, max_y = #matrix[1], #matrix
    local grid = { flow = 'y' }
    for y = 1, max_y do
        local row = { flow = 'x' }
        for x = 1, max_x do
            row[#row+1] = { type = 'button', text = textproxy(matrix, x, y), height = false }
        end
        grid[#grid+1] = row
    end
    return grid
end

local data = {
    {"-/-", "col a", "col b", "col c"},
    {"1:",  "a1",   "b1",   "c1"    },
    {"2:",  "a2",   "b2",   "c2"    },
    {"3:",  "a3",   "b3",   "c3"    },
    {"4:",  "a4",   "b4",   "c4"    },
    {"5:",  "a5",   "b5",   "c5"    },
}
local grid = new_grid_from_matrix(data)
local layout = Layout(grid)
layout:show()

I replaced the button's text field (that is usually a string) by a special table with custom meta.__tostring handler to return the string value.

To support this approach LUIGI needs some small changes. I suppose there are other part of code to change to fully support text proxy.

Let me know what are you thinking about this feature.

See my current small changes.

Regards,

airstruck commented 7 years ago

All "widget attributes" like text can be set to a function instead of a fixed value. This should work:

row[#row+1] = {
    type = 'button', height = false,
    text = function () return matrix[y][x] end,
}

That function takes the widget as the first argument, so if you don't like creating a separate function for each widget, you could do something like this instead:

local function gridButtonText (self)
    return self.stuff.matrix[self.stuff.y][self.stuff.x]
end

-- ...

row[#row+1] = {
    type = 'button', height = false,
    stuff = { x = x, y = y, matrix = matrix },
    text = gridButtonText,
}