bevy_animation_graph_editor 0.10.0

Animation graph editor for the Bevy game engine
Documentation
use bevy::{
    asset::{Asset, AssetId, AssetServer, Assets, Handle},
    ecs::world::World,
};

use crate::ui::{
    generic_widgets::tree::{Tree, TreeWidget, paths::PathTreeRenderer},
    utils::{asset_sort_key, handle_path_server},
};

pub struct AssetPicker<'a, A: Asset> {
    pub handle: &'a mut Handle<A>,
    pub id_hash: egui::Id,
    pub world: &'a mut World,
}

impl<'a, A: Asset> AssetPicker<'a, A> {
    pub fn new_salted(
        handle: &'a mut Handle<A>,
        world: &'a mut World,
        salt: impl std::hash::Hash,
    ) -> Self {
        Self {
            handle,
            id_hash: egui::Id::new(salt),
            world,
        }
    }
}

impl<'a, A: Asset> egui::Widget for AssetPicker<'a, A> {
    fn ui(self, ui: &mut egui::Ui) -> egui::Response {
        ui.push_id(self.id_hash, |ui| {
            self.world.resource_scope::<Assets<A>, _>(|world, assets| {
                let asset_server = world.resource::<AssetServer>();
                let mut asset_ids: Vec<_> = assets.ids().collect();
                asset_ids.sort_by_key(|id| asset_sort_key(*id, asset_server));
                let paths = asset_ids
                    .into_iter()
                    .map(|id| (handle_path_server(id.untyped(), asset_server), id))
                    .collect();
                let path_tree = Tree::from_paths(paths);
                TreeWidget::new_salted(
                    path_tree,
                    PathTreeRenderer {
                        is_selected: {
                            let selected_id = self.handle.id();
                            Box::new(move |_, v: &AssetId<A>| *v == selected_id)
                        },
                    },
                    "asset picker tree",
                )
                .show(ui, |result| {
                    if let Some(id) = result.clicked
                        && let Some(handle) = asset_server.get_id_handle(id)
                    {
                        *self.handle = handle;
                    }
                })
            })
        })
        .inner
    }
}