#Sidebar on Bevy UI, lots of text to update, there has to be a better way than this

15 messages · Page 1 of 1 (latest)

silver forge
#

Hi, I am in the process of converting my UI from egui to bevy's own, and I'm getting anxious about the mess that is my sidebar at the moment. It would be ideal if there was a way for the sidebar to "refresh" itself taking the values it needs, but I can't get my head around it for some reason. This is a minimal example of what I have came up with at the moment, is there a better way? Does anyone have examples of something similar? Thanks in advance.

#[derive(Clone, Component, Copy)]
pub (super) enum SidebarSections {
    Clock,
    // ...
}

pub (super) fn sidebar_setup (
    parent:         &mut ChildBuilder,
    asset_server:   &Res<AssetServer>,
) {

    let sidebar_entries = IndexMap::from([
        ("Clock placeholder",       Some(SidebarSections::Clock)),
        ("------------------",      None),
        // ...
    ]);

    for (text, marker_maybe) in sidebar_entries.iter() {

        let section = TextBundle::from_section(
            text.to_string(),
            TextStyle {
                font:       asset_server.load(settings::UI_FONT),
                font_size:  settings::UI_TEXT_SIZE,
                color:      settings::UI_TEXT_COLOR
            }
        );

        if let Some(marker) = marker_maybe {
            parent.spawn((section, *marker));
        } else {
            parent.spawn(section);
        }
    }
}

pub (super) fn sidebar_update (
    clock:          Res<time::clock::Clock>,
    mut text_query: Query<(&mut Text, &SidebarSections)>,
) {

    for (mut text, section) in &mut text_query {

        match section {

            SidebarSections::Clock => {
                text.sections[0].value = format!("{}\n", clock.military_time());
            },
        },

        // ...
    }
}
little saddle
#
  1. You might consider using something like sickle_ui to make creating the sidebar more ergonomic (to avoid using the childbuilder stuff)
  2. Consider making widgets for each thing you dock in the sidebar.
  3. There are two update strategies I like to use.
    3a. Tag different parts of widgets with components, then write systems that query over and update those components.
    3b. Store entity references on some component, query for that and then use the entity references to update. This is good if you have some entity commands associated with your widgets.
  4. Implement entity commands for your widgets like "set_text" for a label and use those to write more concise update code.

Don't go for One System to Rule Them All. Write more concise systems that are responsible for updating either single widgets or just parts of widgets.

I can provide examples if you'd like. I've written extensive bevy ui.

silver forge
little saddle
#

I'll write a blog post later today and link it to you that will cover how I do this stuff.

woeful kindle
#

Always consider using Changed<> when you can. Agree with using many small systems and small components

thorn pine
little saddle
#

I didn't write it yet. I'll do that now.

thorn pine
#

I tried several ways, and I believe the cleanest looking one was making a tag for each component
but
that also means I have over twenty tags in my code just for ui

little saddle
thorn pine
little saddle
#

no prob

thorn pine
silver forge
molten echo
little saddle