slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
16.93k stars 566 forks source link

Table View #1316

Closed cppdev123 closed 1 year ago

cppdev123 commented 2 years ago

Currently slint does not have a table view but only a list view however a list view is a table view which only has one column so I have the following ideas for implementing table view:

Why not draw rows for list view instead of cells for a table (the current approach) ? the current approach lacks a main benefit of tables : rows and columns should have consistent width and height. Currently the user must right code to ensure that items in the rows have equal width which is not always an easy to do especially when text is involved since

Another improvement for models: There should be some sort of decoration role, font role, display role, etc. Cause it is very common to use and will save the time to code them manually each time for each table and list

ogoffart commented 2 years ago

Thanks for the comments. There are already some discussion about tableview in #759 and #574

  • the table has a model which notifies it for each insertion, deletion and changing of an item

Right, the current Model used by the repeater and the ListView currently already do that.

  • the table has a delegate which is responsible for painting the items and determining their size hint (just like in qt)

Yes, the ListView also has that, in the for

  • the table have a state for each column which contains : min and max height and width, total height and width and average height and width

Right, a TableView need that. This could be supported by a runtime layouting function, like there is one for the ListView, it also need to compute the size of each column.

The problem is that we probably do not want to instentiate every elements in the model. But without instentiating it can be hard or impossible to know the size. unless we make something special that'd allow us to query the size without instentiating the component.

  • when painting the table will provide the delegate the min, max or average width and height depending on the user choosing or a fixed width or height if the user chooses so

The row of the table would just be Component, but these Component must have different column in it and would be able to query the size of each column from the TableView

  • a list is a simplified table with one column with a simplified model

Kind of, yes. Another way to say it is that a Table is a generalized List

Why not draw rows for list view instead of cells for a table (the current approach) ? the current approach lacks a main benefit of tables : rows and columns should have consistent width and height.

Yes, that's the missing part.

There should be some sort of decoration role, font role, display role, etc. Cause it is very common to use and will save the time to code them manually each time for each table and list

This is what the StandardListViewItem is meant to be, but it currently only has "display" right now.


Now, the question is how would the model be. What's the type in sline. For example, a ListView uses [StandardListViewItem] then a TableView would use a [[StandardListViewItem]] ? (a model of model)

Or would we have something better where the delegate can basically take any value from the model struct.

So this could be looking like:

property <[{foo: string, bar: string}]> model;
tb := TableView {
   for data in model: HorizontalLayout {
      t1 := Text { width: tb.col-width(0); text: data.foo; }  // column1
      t2 := Text { width: tb.col-width(1); text: data.bar; }  // column2
   }
}

But this doesn't allow to compute the size of the column easily from the content. Another alternative:

property <[{foo: string, bar: string}]> model;
tb := TableView {
   for data in model: TableRow {
      Text { text: data.foo; }  // column1
      Text { text: data.bar; }  // column2
   }
}

or

StandardTableView := StandardView {
   property <[[StandardListViewItem]]> model;
   for data in model: TableRow {
      for data2 in data : Xxx { ... }
   }
}
ogoffart commented 1 year ago

Here is an example of a table view built on top of a ListView: https://slint-ui.com/docs/rust/slint/docs/recipes/index.html#table-view

tronical commented 1 year ago

Florian implemented and merged an initial version of StandardTableView in https://github.com/slint-ui/slint/pull/2032 . I suppose the acceptance criteria for closing this issue though is a more generic mechanism?

ogoffart commented 1 year ago

Table View is in 0.3.4. Further features are tracked in https://github.com/slint-ui/slint/issues/2033