WIP: More advanced example

This commit is contained in:
JMS55 2023-12-12 19:47:14 -08:00
parent 8dcaae99e1
commit a61ee7e0b2
6 changed files with 104 additions and 52 deletions

View file

@ -26,4 +26,4 @@ bevy_utils = { git = "https://github.com/JMS55/bevy", branch = "query_new_12" }
bevy_window = { git = "https://github.com/JMS55/bevy", branch = "query_new_12" }
[[example]]
name = "basic"
name = "demo"

View file

@ -1,42 +0,0 @@
use bevy::{
app::{App, Startup},
core_pipeline::{clear_color::ClearColor, core_2d::Camera2dBundle},
ecs::system::{Commands, ResMut},
render::color::Color,
ui::node_bundles::NodeBundle,
DefaultPlugins,
};
use bevy_dioxus::{
bevy_mod_picking::DefaultPickingPlugins, dioxus::prelude::*, hooks::use_system, 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::new(ui_root),
node_bundle: NodeBundle::default(),
});
commands.spawn(Camera2dBundle::default());
})
.run();
}
fn ui_root(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
let change_clear_color = use_system(cx, |mut clear_color: ResMut<ClearColor>| {
clear_color.0 = Color::RED;
});
render!(
div {
onclick: move |_| {
count += 1;
change_clear_color.schedule();
},
"Count: {count}"
}
)
}

73
examples/demo.rs Normal file
View file

@ -0,0 +1,73 @@
use bevy::{
app::{App, Startup},
core::DebugName,
core_pipeline::core_2d::Camera2dBundle,
ecs::{entity::Entity, query::Without, system::Commands},
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::new(Editor),
node_bundle: NodeBundle::default(),
});
commands.spawn(Camera2dBundle::default());
})
.run();
}
#[component]
fn Editor(cx: Scope) -> Element {
let selected_entity = use_state(cx, || Option::<Entity>::None);
render! {
SceneTree { selected_entity: selected_entity }
EntityInspector { selected_entity: selected_entity }
}
}
#[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);
render! {
div {
flex_direction: "column",
if entities.is_empty() {
rsx! { "No entities exist" }
} else {
rsx! {
for (entity, name) in entities {
div {
onclick: move |_| selected_entity.set(Some(entity)),
background_color: if Some(entity) == ***selected_entity { INDIGO_600 } else { NEUTRAL_800 },
format!("{name:?}")
}
}
}
}
}
}
}
#[component]
fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> Element {
render! {
if selected_entity.is_none() {
"Select an entity to view its components"
} else {
"TODO: Component widgets"
}
}
}

View file

@ -3,6 +3,7 @@ use bevy::{
ecs::{entity::Entity, system::Commands},
hierarchy::BuildChildren,
prelude::default,
render::color::Color,
text::{Text, TextStyle},
ui::{
node_bundles::{NodeBundle, TextBundle},
@ -111,7 +112,10 @@ pub struct BevyTemplate {
}
enum BevyTemplateNode {
Node { style: Style, children: Box<[Self]> },
Node {
style: (Style, BackgroundColor),
children: Box<[Self]>,
},
TextNode(Text),
}
@ -150,7 +154,7 @@ impl BevyTemplateNode {
Self::TextNode(Text::from_section(*text, TextStyle::default()))
}
TemplateNode::Dynamic { id: _ } => Self::Node {
style: Style::default(),
style: Default::default(),
children: Box::new([]),
},
TemplateNode::DynamicText { id: _ } => {
@ -166,17 +170,23 @@ impl BevyTemplateNode {
children_to_parent: &mut EntityHashMap<Entity, Entity>,
) -> Entity {
match self {
BevyTemplateNode::Node { style, children } => {
BevyTemplateNode::Node {
style: (style, background_color),
children,
} => {
// TODO: Can probably use with_children() instead
let children = children
.iter()
.map(|child| child.spawn(commands, parent_to_children, children_to_parent))
.collect::<Box<[_]>>();
let parent = commands
.spawn(NodeBundle {
style: style.clone(),
..default()
})
.spawn((
NodeBundle {
style: style.clone(),
..default()
},
background_color.clone(),
))
.push_children(&children)
.id();
for (i, child) in children.iter().enumerate() {
@ -195,8 +205,9 @@ impl BevyTemplateNode {
}
}
fn parse_style_attributes(attributes: &[TemplateAttribute]) -> Style {
fn parse_style_attributes(attributes: &[TemplateAttribute]) -> (Style, BackgroundColor) {
let mut style = Style::default();
let mut backgroud_color = BackgroundColor::default();
for attribute in attributes {
if let TemplateAttribute::Static {
name,
@ -211,9 +222,15 @@ fn parse_style_attributes(attributes: &[TemplateAttribute]) -> Style {
("display", "none") => style.display = Display::None,
("position", "relative") => style.position_type = PositionType::Relative,
("position", "absolute") => style.position_type = PositionType::Absolute,
("flex-direction", "column") => style.flex_direction = FlexDirection::Column,
("background-color", hex) => {
backgroud_color.0 = Color::hex(hex).expect(&format!(
"Encountered unsupported bevy_dioxus background-color `{value}`."
))
}
_ => panic!("Encountered unsupported bevy_dioxus attribute `{name}: {value}`."),
}
}
}
style
(style, backgroud_color)
}

3
src/colors.rs Normal file
View file

@ -0,0 +1,3 @@
pub const NEUTRAL_800: &'static str = "#27272a";
pub const INDIGO_600: &'static str = "#4f46e5";

View file

@ -1,4 +1,5 @@
mod apply_mutations;
pub mod colors;
mod deferred_system;
mod events;
pub mod hooks;