-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
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
stretch
dependency and implements a custom layout engine based on thedruid
codebase, 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,
stretch
forced 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
stretch
and upgrading was not straightforward (#4). The upgrade would have entailed keeping aStretch
type around and mutating it as layout changes.Moreover, computing layout with
stretch
was very slow. On my system, computing the layout of the "Text" screen in thetour
example 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
Widget
is in charge of computing its boundaries inside the providedlayout::Limits
.This way, complex widgets like
Column
andRow
can distribute contents in a flex-like way, while simpler widgets likeButton
perform 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
Container
widget has been added, allowing us to perform both horizontal and vertical alignment without the need of a "direction". Because of this, theJustify
type has been dropped.Align
will most likely change too.Finally, the changes have been mostly internal. All the examples should be working as before!
Closes #4.
Changelog
Added
Container
widget which allows easy alignment with methods likecenter_x
andcenter_y
Widget::width
andWidget::height
, which should be implemented properly by widgets.Changed
Widget::node
has been changed toWidget::layout
and it now computes the boundaries directly.max_width
andmax_height
methods now take au32
instead of aLength
.Removed
stretch
dependencyJustify
type,justify_content
andalign_self
methods