Chapters

State Rules

A state rule holds only while its view is in a state, such as hovered. Rules set inside it reach every view under that view.

Hover and press the buttons.

fn main() {
    let mut ui = Ui::new(Warm);
    let node = ui.build(|cx| {
        text("Save")
            .when_in::<Hovered, _>(|cx: &mut Cx<Toy, Warm>| {
                cx.set::<Text>(|t, _| t.size(20.0));
            })
            .build(cx)
    });
    assert_eq!(ui.size(node), 14.0);

    ui.world.nodes[node].hovered = true;
    ui.mounted.mark_dirty(node);
    ui.frame();
    assert_eq!(ui.size(node), 20.0);
}

Nothing is rebuilt when the state changes. The backend reports the node to mark_dirty, and the next frame writes the props the rule changed.

States

A state is a type that implements Condition: whether the state holds on a node, and a request to the backend to report the node whenever that changes.

struct Hovered;

impl Condition<Toy> for Hovered {
    fn holds(world: &World, node: usize) -> bool {
        world.nodes[node].hovered
    }

    fn watch(_: &mut World, _: usize) {
        // A real backend hooks its hover events up to `mark_dirty`.
    }
}

States in Bevy

Bevy Fynix’s states are components: Hovered, Pressed, Focused, Dragging, Entering and Leaving, and any component of your own works too. .when::<S, _>(..) holds while the view’s root has the component S.

button(label("Save"))
    // Every label in the button turns accent on hover.
    .when::<Hovered, _>(|cx: &mut Cx<Bevy, MyTheme>| {
        cx.set::<Label>(|l, _| l.tone(Tone::Accent));
    })
    .transition(Motion::Interact)

On the root, a state rule beats its call site. On a view under it, it only fills what that view’s call site left unset.

Coming In and Going Out

.appear(away) uses Entering and Leaving to animate a view into the tree from the look away sets, and back out to it. hidden is a ready-made away: every element transparent and the root scaled down a little. It needs a transition to move.

line(name).appear::<MyTheme>(hidden).transition(Motion::Expand)