Cuicui Layout
A dumb layout algorithm you can rely on, built for and with bevy.
For some reasons, the Cyberpunk main menu has become the 7GUI of bevy, so here
is the Cyberpunk main menu using cuicui_layout_bevy_ui
.
Code
cmds.spawn;
let menu_buttons = ;
let title_card = serv.;
let font = serv.load;
let bg = serv.load;
let board = serv.load;
let button = serv.load;
layout!
Running examples
Use the cargo run --bin
command to list possible examples, and run them.
We do this because it allows us to have different dependencies between examples.
Stability
This crate is in expansion, use at your own risk, it is extremely likely that a lot of things are going to break a lot.
Using cuicui_layout
- Chose which crate you want to use:
- Interested in a ready-made UI library on top of
bevy_ui
?cuicui_layout_bevy_ui
is for you! - Want more flexibility? Using
cuicui_layout
on top ofbevy_sprite
will let you integrate your UI with a lot of 3rd party crates that only work with sprites!cuicui_layout_bevy_sprite
is for you! - Using a custom renderer or want your UI to be part of the 3D environment?
Build on top of
cuicui_layout
itself then!
- Interested in a ready-made UI library on top of
- Add the chosen crate as a dependency to your crate.
cargo add cuicui_layout_bevy_ui
- Use the
layout!
macro to build a UI (text representation coming soon). - That's it! You are now using
cuicui_layout
, congratulations! Make sure to check theLayoutType
docs to learn the current capabilities ofcuicui_layout
.
Please note that cuicui_layout
won't magically make sprite components work in
UI nodes.
cuicui_layout
crates
This repository contains several crates:
cuicui_layout
(layout): The base algorithm and components, does not make any assumption about how it is used, beside the requirement that layout nodes be bevyEntitiy
and usesbevy_hierarchy
.cuicui_layout_bevy_ui
(ui): Integration withbevy_ui
, including extension toLayoutType
forUiImage
,Text
, background images and background colors.cuicui_layout_bevy_sprite
(sprite):bevy_sprite
integration, supportsMesh2dHandle
,Sprite
andText2d
. This isn't as good as thebevy_ui
-based integration when it comes to content-driven sizes, but otherwise should work very much like thebevy_ui
integration.
(maybe cuicui_layout_spec
in the future)
Cargo features
cuicui_layout_bevy_sprite/sprite_text
(on by default): implement content-sized layout nodes forText2dBundle
.cuicui_layout/reflect
(on by default): Derivebevy_reflect
traits for cuicui_layout types & register them.
Why cuicui layout
- Friendly algo with less things to keep in your head and good defaults.[^1]
- Uses and takes full advantage of the bevy ECS.
- Only controls
PosRect
, notTransform
, you need to add a system that setsTransform
based onPosRect
. - Fully flexible and extensible, can be used with
bevy_ui
,bevy_sprite
, your own stuff. - Fantatstically easy to extend, like really.
- Helpful and fully detailed error messages when things are incoherent or broken. As opposed to FlexBox, which goes "this is fine π₯πΆπ₯" and leaves you to guess why things do not turn out as expected.
[^1]: aspirational, currently not really the case.
Why not Flexbox
You are writing text to get 2d visual results on screen.
The translation from text to screen should be trivial, easy to do in your head.
Otherwise you need visual feedback to get what you want.
Bevy, even with hot reloading or bevy-inspector-egui
will always have extremely slow visual feedback.
Flexbox has too many parameters and depends on implicit properties of UI elements, it is not possible to emulate it in your head.
cuicui's layout in contrast to Flexbox is easy to fit in your head. In fact, I will forecefully push cuicui's layout algorithm in your head in two short bullet points.
- A node can be a
Node::Container
and distribute its children along aDirection
either by evenly spacing them (Distribution::FillParent
) or putting them directly one after another (Distribution::Start
). - A
Container
's size can be expressed as a static value, a fraction of the size of what contains it, or a multiple of what it contains. - The content of a
Container
can beAlignment
to the start, end or center of its parent (by default it's centered).
That's it. There are some edge cases, but cuicui will yell at you
tell you nicely when you hit them and tell you how to handle them properly.
Flexbox FAQ
Q: Where is padding
?
A: padding
is equivalent to margin
in cuicui_layout. margin
and border
doesn't make conceptual sense.
Q: How do I center a node?
A: Add an empty node at the start and end of the container, and use fill_parent
Q: What is the equivalent of flex_direction
?
A: use row
and column
Q: What are the equivalents of column-reverse
and row-reverse
?
A: None. Use Alignment::End
and swap your elements! Note that the *-reverse
flows in flexbox are very useful for internationalization. However,
when making a game, it is not enough to just swap the elements! Artistic control is
paramount and internationalization needs to be taken as a whole in the context of the UI.
Q: What is the equivalent of flex_wrap
?
A: None, do you really need it?
Q: What is the equivalent of align_item
, align_self
, align_content
, justify_content
?
A: After 5 years of working with CSS, I still have no clue which one does what,
and whether they really do anything, so I wont' adventure an asnwer.
Q: What is the equivalent of flex_grow
, flex_shrink
, flex_basis
, gap
?
A: Do you even know what they do?
Q: Why can't child container overflow their parents? A: It's likely you didn't expect this, so we report it as an error.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.