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

Advanced layout strategies (grid, floating text, etc.) #34

Open
hecrj opened this issue Oct 23, 2019 · 5 comments
Open

Advanced layout strategies (grid, floating text, etc.) #34

hecrj opened this issue Oct 23, 2019 · 5 comments
Labels
feature New feature or request help wanted Extra attention is needed layout text
Milestone

Comments

@hecrj
Copy link
Member

hecrj commented Oct 23, 2019

Currently, iced_native only supports flexbox items. For instance, it is not possible to create a grid of items or make text float around an image.

We will need to enhance the layouting engine to support different strategies and improve the way we measure text to lay it out in a more flexible way.

@hecrj hecrj added the feature New feature or request label Oct 23, 2019
@hecrj hecrj added this to the 1.0.0 milestone Oct 23, 2019
@hecrj hecrj added the help wanted Extra attention is needed label Oct 23, 2019
@virtualritz
Copy link

virtualritz commented Dec 24, 2019

I like to mention elm-ui for inspiration – as an alternative to CSS concepts.
There is also a talk from its author on youtube.

@virtualritz
Copy link

A, kindly ignore. I just saw that elm-ui is already on your radar. :)

@nicoburns
Copy link
Contributor

nicoburns commented Apr 18, 2020

You may wish to consider using https://github.com/vislyhq/stretch for layout It's a full flexbox implementation, with support for absolute positioning. CSS grid support is stated goal, although it's not currently implemented.

EDIT: Stretch has become unmaintained, but has a well maintained fork in Taffy (https://github.com/DioxusLabs/taffy)
EDIT2: I ended up implementing CSS Grid support myself. It's available as of Taffy 0.3.0.

@nicoburns
Copy link
Contributor

@hecrj I've been looking into what it would take to implement Taffy's layout modes (Flexbox and CSS Grid) as an Iced widget. I have a working prototype of a Grid widget at https://github.com/nicoburns/iced_taffy (checkout the nested example if you are interested).

Based on the experience of making this prototype I have a bit of a laundry list of changes to Iced that I'd like in order to make such an integration easier and more efficient:

  1. Add a measure method to Widget trait
    This would be similar to layout, but only returns a size rather than recursively returning child layouts. Taffy's layout modes often require measuring children multiple times so it's important that this is as cheap as possible. And it is often much cheaper to merely compute the size of widget than it is to recursively layout the widget and all of it's descendants.

    This method should take &mut self rather than &self to enable caching of the results. The caching is useful even within a single frame (/relayout) and is crucial for performance (in our benchmarks it turns the time complexity of layout from "exponential with respect to the depth of the tree" to "linear with respect to the total number of nodes" leading to wall time improvements of several orders of magnitude for trees even a few nodes (e.g. 7) deep).

  2. Have the layout method on Widget trait take &mut self instead of &self (possibly not currently useful)
    Same reason (caching) as above. Although I'm not quite sure what Iced's story on change detection is. I think I read somewhere that Iced currently unconditionally rerenders everything on each frame, in which case this may not be useful yet.

  3. Add setters for fill property of layout::Limits
    I need precise control of the Limits beyond what is provided by the current methods. I'm currently working around this by carefully calling multiple methods, but this is quite awkwards.

  4. Ability to move children out of layout::Node
    I need to obtain the recursive child layouts out of layout::Node but override the bounds with my own computations. I am currently able to workaround this by cloning the children Vec, but this introduces an unncessary clone.

There are other things I'd potentially like in future such as:

  • Extra parameters to layout/measure that make it possible to request both a "min-content" and "max-content" size from a child (which enables better content-sizing of widgets that support wrapping).
  • Support for clipping a widget such that it's restricted to rendering within certain bounds
  • Better support for rendering multiple layers of content so that we can support position: absolute or some similar layer mechanism

But I believe the above (particularly the measure method) would be sufficient to get to the point where I could sensibly release a generally usable version of iced_taffy with acceptable performance for large trees.

Would you be open to PR's that made these changes?

@nicoburns
Copy link
Contributor

Update: Just saw #52 and wanted to add that:

  • The performance issues have been solved in recent versions of Taffy (see benchmarks)
  • The "all or nothing" nature of Taffy is also in the process of being fixed. Once this PR (WIP: Refactor the LayoutTree trait DioxusLabs/taffy#326) lands it will be possible to use Taffy to layout a single widget much like Iced's existing Row/Column widget work, which will mean that Taffy's layout modes can be mixed and matched with other simpler layout modes as desired. The iced_taffy prototype is based on this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request help wanted Extra attention is needed layout text
Projects
None yet
Development

No branches or pull requests

3 participants