-
Notifications
You must be signed in to change notification settings - Fork 756
Lay out grids at runtime rather than at compile time #9572
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is going in the right direction.
We'll have to have good documentation for the exact behavior and tests.
) -> Vec<LayoutData> { | ||
orientation: Orientation, | ||
) -> (Vec<LayoutData>, Vec<GridLayoutCellData>) { | ||
let mut cells: Vec<GridLayoutCellData> = data.to_vec(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slightly concerned about the extra allocation here at runtime. But I hope this is fine and we can optimize later if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, maybe I could change the generated code to generate a Vec (that I can mutate) instead of
&sp::GridLayoutData { cells: sp::Slice::from_slice(&[ ... ]) )
?
Phew ;-)
Documentation, I agree (will do). |
63da9fb
to
04f0bdc
Compare
Now including row and col properties, implemented using the layout cache. The other issue is the one mentioned in the commit log: how to react to changes to row/col and trigger layouting again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works, but it has an issue: if e.g. a widget's text property is set to "row" or "col", it creates an infinite recursion on the layout-cache binding, incorrectly.
I see, because the row and col are both input and output of the layout computation?
It makes sense to x,y,width,height to depend on the widget text, but not for row and col. So I should create a different kind of cache for that?
Perhaps it would help to have another property to cache these values instead of doing it all in solve_layout, yes.
(Then we would also not need this cache if the row and col are entirely known at compile time)
But this can be a known issue and doesn't need to be solve, as long as it is detected at compile time and the logic in the binding_analysis that detect the loop is catching that properly.
Hmm, solve_grid_layout returns the x,y,width,height cache (for use in the property binding for layoutcache) and takes the spec from the user as input, so row/col determination has to happen in there too (it's obviously needed to determine x,y,width,height)... but the result of that row/col determination needs to be stored into another property... I wonder how. The current solution is already to duplicate the input data between layoutcache (the call to solve_grid_layout) and layoutinfo (the call to grid_layout_info). Somehow we should be able to extract that into a function that returns a Vec, that I could also use from the third property that is computed from that same data?
That is an excellent idea, it would address your concern about memory usage.
Yes, it's caught properly, but it's still a bug, and one that requires a big refactoring of the code in this MR. But indeed if we want the feature already (or if you simply want to avoid re-reviewing the same thing many times), you can merge this and I can build on top. |
04f0bdc
to
d5fcbb7
Compare
I was wrong, this works well in an interactive testcase. It just doesn't work in a unittest like |
Maybe something like
|
d5fcbb7
to
04ea92e
Compare
Thanks, this worked, now the new test passes (both when compiled and when interpreted) |
This includes support for row and col properties to be expressions rather than just constants.
04ea92e
to
d60dddd
Compare
ChangeLog: the row, col, rowspan and colspan properties can now be expressions rather than having to be constants. The layout adapts when the value of the expression changes.
I quite like this idea, actually. I am currently implementing this solution, on top of this MR, to make this cleaner and solve the binding loop.
A new property "layout-organized-data" contains the result of the call that uses the input data to determine row/col values and store that into the organized data (which is a SharedVector in order to reuse the LayoutCacheAccess mechanism, just on a different cache property), and this (plus layout constraints...) will be the source of information for both solve_grid_layout and grid_layout_info. Currently only implemented for the interpreter (works 100% - grid_layout_data() reads from the organized data and adds the constraints, it all works including a text property that uses row and col), I will now work on the compiler side of things. |
This opens the door for using computed values in "row"/"col" properties, and later on for dynamic grid layouts (for/if support)
PROBLEM: it's missing the "row" and "col" properties from my previous commit... This is WIP, so we can discuss how to bring those properties back.