Custom layout engine#52
Conversation
Remove `align_self` and `justify_content` methods
This speeds up layouting in the most common scenario considerably! :tada:
|
Nice work ! |
|
@Matthias-Fauconneau Thanks!
Have you read both the |
|
I read both, maybe I'm just not familiar enough with modern UI architecture.
I am suggesting presenting the contrasts more explicitly could be useful to
newcomers who need help deciding before knowing the difference between Elm
and data-orientied. (Which I still don't) :)
|
I agree. However, I think both Moreover, I don't think I am familiar enough with In any case, I plan to build some bridges for collaboration soon! |
|
Maybe expand on https://raphlinus.github.io/ui/druid/2019/11/22/reactive-ui.html explaining how iced currently fits in that framework ? |
This PR drops the
stretchdependency and implements a custom layout engine based on thedruidcodebase, which is in turn inspired by Flutter. The main reasons for this change are simplicity, intuitiveness, and performance.Flexbox, while powerful, is hard to use properly. Many of the styling properties of a flex node are tied to the parent
flex-direction. This makes specific constraints very hard to encode (fill width/height, horizontal/vertical alignment, etc.). I think specific constraints like these are the ones users care about in the end.Additionally,
stretchforced us to turn every single node of the layout system into a flex node. This meant that even very simple nodes that did not have complex layout needs would still be seen as complex flex nodes by the layout algorithm.Furthermore, we were using an old version of
stretchand upgrading was not straightforward (#4). The upgrade would have entailed keeping aStretchtype around and mutating it as layout changes.Moreover, computing layout with
stretchwas very slow. On my system, computing the layout of the "Text" screen in thetourexample took around 4 ms. I think this could be related to using an old version and some odd behavior that I had to work around.The new layout engine is very straightforward: each
Widgetis in charge of computing its boundaries inside the providedlayout::Limits.This way, complex widgets like
ColumnandRowcan distribute contents in a flex-like way, while simpler widgets likeButtonperform simple computations.The new system is way faster. During my testing I have noticed a speedup of around 2 orders of magnitude in the best case (text measure cache hits) and 1 order of magnitude in the worst case (text measure cache misses). For instance, the "Text" screen I mentioned before now takes around 40 μs in the best case and 100 μs in the worst case. Debug mode is actually usable now! 🎉
In addition, a new
Containerwidget has been added, allowing us to perform both horizontal and vertical alignment without the need of a "direction". Because of this, theJustifytype has been dropped.Alignwill most likely change too.Finally, the changes have been mostly internal. All the examples should be working as before!
Closes #4.
Changelog
Added
Containerwidget which allows easy alignment with methods likecenter_xandcenter_yWidget::widthandWidget::height, which should be implemented properly by widgets.Changed
Widget::nodehas been changed toWidget::layoutand it now computes the boundaries directly.max_widthandmax_heightmethods now take au32instead of aLength.Removed
stretchdependencyJustifytype,justify_contentandalign_selfmethods