bevy_dioxus/examples/demo.rs

138 lines
4.5 KiB
Rust
Raw Normal View History

2023-12-13 03:47:14 +00:00
use bevy::{
app::{App, Startup},
2023-12-17 05:21:32 +00:00
core::{DebugName, Name},
2023-12-13 03:47:14 +00:00
core_pipeline::core_2d::Camera2dBundle,
2023-12-17 05:33:13 +00:00
ecs::{entity::Entity, query::Without, system::Commands, world::World},
2023-12-13 03:47:14 +00:00
ui::{node_bundles::NodeBundle, Node},
DefaultPlugins,
};
use bevy_dioxus::{
bevy_mod_picking::DefaultPickingPlugins, colors::*, dioxus::prelude::*, hooks::*,
DioxusUiBundle, DioxusUiPlugin, DioxusUiRoot,
};
fn main() {
App::new()
.add_plugins((DefaultPlugins, DioxusUiPlugin, DefaultPickingPlugins))
.add_systems(Startup, |mut commands: Commands| {
commands.spawn(DioxusUiBundle {
dioxus_ui_root: DioxusUiRoot(Editor),
2023-12-13 03:47:14 +00:00
node_bundle: NodeBundle::default(),
});
2023-12-17 05:21:32 +00:00
commands.spawn((Camera2dBundle::default(), Name::new("Camera")));
2023-12-13 03:47:14 +00:00
})
.run();
}
#[component]
fn Editor(cx: Scope) -> Element {
2023-12-16 04:31:00 +00:00
// TODO: When selected entity is despawned, need to reset this to None
2023-12-13 03:47:14 +00:00
let selected_entity = use_state(cx, || Option::<Entity>::None);
render! {
2023-12-17 04:59:19 +00:00
div {
width: "100vw",
height: "100vh",
justify_content: "space-between",
SceneTree { selected_entity: selected_entity }
EntityInspector { selected_entity: selected_entity }
}
2023-12-13 03:47:14 +00:00
}
}
#[component]
fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> Element {
let entities = use_query_filtered::<(Entity, DebugName), Without<Node>>(cx);
let entities = entities.query();
let mut entities = entities.into_iter().collect::<Vec<_>>();
entities.sort_by_key(|(entity, _)| *entity);
2023-12-17 05:33:13 +00:00
let spawn_entity = use_system(cx, |world: &mut World| {
world.spawn_empty();
});
2023-12-13 03:47:14 +00:00
render! {
div {
2023-12-16 04:31:00 +00:00
onclick: move |_| selected_entity.set(None),
2023-12-13 03:47:14 +00:00
flex_direction: "column",
if entities.is_empty() {
rsx! { "No entities exist" }
} else {
rsx! {
for (entity, name) in entities {
div {
onclick: move |_| {
if Some(entity) == ***selected_entity {
selected_entity.set(None);
2023-12-17 20:19:08 +00:00
} else {
selected_entity.set(Some(entity));
}
},
2023-12-17 05:21:32 +00:00
padding: "8",
2023-12-13 03:47:14 +00:00
background_color: if Some(entity) == ***selected_entity { INDIGO_600 } else { NEUTRAL_800 },
2023-12-17 05:21:32 +00:00
match name.name {
Some(name) => format!("{name}"),
_ => format!("Entity ({:?})", name.entity)
}
2023-12-13 03:47:14 +00:00
}
}
}
}
2023-12-17 05:33:13 +00:00
div {
onclick: move |_| spawn_entity(),
padding: "8",
background_color: NEUTRAL_800,
"Spawn Entity"
}
2023-12-13 03:47:14 +00:00
}
}
}
#[component]
fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> Element {
let world = use_world(cx);
let components = if let Some(selected_entity) = selected_entity.get() {
let entity_ref = world.get_entity(*selected_entity).unwrap();
let archetype = entity_ref.archetype();
2023-12-17 20:19:08 +00:00
let mut components = archetype
.components()
.map(|component_id| {
let info = world.components().get_info(component_id).unwrap();
let name = info.name();
2023-12-17 20:19:08 +00:00
(name, component_id, info.type_id(), info.layout().size())
})
.collect::<Vec<_>>();
components.sort_by(|(name_a, ..), (name_b, ..)| name_a.cmp(name_b));
components
} else {
vec![]
};
2023-12-13 03:47:14 +00:00
render! {
if selected_entity.is_none() {
rsx! {
2023-12-17 20:19:08 +00:00
"Select an entity to view its components"
}
2023-12-13 03:47:14 +00:00
} else {
rsx! {
div {
flex_direction: "column",
2023-12-17 20:19:08 +00:00
for (name, _component_id, _type_id, _size) in components {
div {
padding: "8",
background_color: NEUTRAL_800,
2023-12-17 20:19:08 +00:00
div {
"Component: {name}"
}
}
}
}
2023-12-17 20:19:08 +00:00
}
2023-12-13 03:47:14 +00:00
}
}
}