diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index e1ce04e..da2ace6 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -31,6 +31,8 @@ import "@storyteller/studio-web/transform-toolbar"; import "./anim-editor.element"; import "./help.element"; +import "./blocking.element"; + import "./app.element.scss"; @customElement("app-root") @@ -149,6 +151,8 @@ export class AppElement extends LitElement { + + ` : nothing} diff --git a/studio-frontend/src/app/blocking.element.scss b/studio-frontend/src/app/blocking.element.scss new file mode 100644 index 0000000..19a9a3d --- /dev/null +++ b/studio-frontend/src/app/blocking.element.scss @@ -0,0 +1,8 @@ +:host { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + position: absolute; + top: 60px; + left: 16px; +} \ No newline at end of file diff --git a/studio-frontend/src/app/blocking.element.ts b/studio-frontend/src/app/blocking.element.ts new file mode 100644 index 0000000..9b88573 --- /dev/null +++ b/studio-frontend/src/app/blocking.element.ts @@ -0,0 +1,41 @@ + +import { LitElement, html, nothing, unsafeCSS } from "lit"; + +import styles from "./blocking.element.scss?inline"; +import { customElement } from "lit/decorators.js"; +import * as studio from "@storyteller/studio"; + +@customElement("sts-blocking") +export class BlockingElement extends LitElement { + static override styles = unsafeCSS(styles); + + override render = () => html` + { + studio.dispatchBlockingCommand(studio.BlockingCommand.Cube); + }}> + Cube + + + { + studio.dispatchBlockingCommand(studio.BlockingCommand.Sphere); + }}> + Sphere + + + { + studio.dispatchBlockingCommand(studio.BlockingCommand.Cylinder); + }}> + Cylinder + + + { + studio.dispatchBlockingCommand(studio.BlockingCommand.Torus); + }}> + Torus + + `; +} \ No newline at end of file diff --git a/studio/src/ui/blocking.rs b/studio/src/ui/blocking.rs new file mode 100644 index 0000000..b32a766 --- /dev/null +++ b/studio/src/ui/blocking.rs @@ -0,0 +1,83 @@ +use std::sync::Arc; + +use bevy::prelude::*; +use bevy_mod_picking::PickableBundle; +use space_editor::prelude::{ + space_undo::{AddedEntity, NewChange}, + *, +}; +use wasm_bindgen::prelude::*; + +use crate::{ + interaction::Selectable, + scene::SceneElement, + wasm::{StaticBuffer, WasmMessageBuffer}, +}; + +pub struct UiBlockingPlugin; + +impl Plugin for UiBlockingPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, read_command_system); + } +} + +fn read_command_system(mut commands: Commands, mut change_event: EventWriter) { + let Some(cmd) = COMMAND.take_message() else { + return; + }; + + let mut new_entity = commands.spawn(( + SpatialBundle::default(), + PrefabMarker, + Selectable, + SceneElement::Mesh, + PickableBundle::default(), + )); + + match cmd { + BlockingCommand::Cube => { + new_entity + .insert(MeshPrimitivePrefab::Cube(1.0)) + .insert(Name::new("Cube")); + } + BlockingCommand::Sphere => { + new_entity + .insert(MeshPrimitivePrefab::Sphere(SpherePrefab { r: 1.0 })) + .insert(Name::new("Sphere")); + } + BlockingCommand::Torus => { + new_entity + .insert(MeshPrimitivePrefab::Torus(TorusPrefab::default())) + .insert(Name::new("Torus")); + } + BlockingCommand::Cylinder => { + new_entity + .insert(MeshPrimitivePrefab::Cylinder(CylinderPrefab::default())) + .insert(Name::new("Cylinder")); + } + }; + + change_event.send(NewChange { + change: Arc::new(AddedEntity { + entity: new_entity.id(), + }), + }); +} + +#[derive(Clone, Copy, Debug)] +#[wasm_bindgen] +pub enum BlockingCommand { + Cube, + Sphere, + Torus, + Cylinder, +} + +static COMMAND: WasmMessageBuffer = WasmMessageBuffer::new(); + +#[wasm_bindgen(js_name = dispatchBlockingCommand)] +pub fn dispatch_command(command: BlockingCommand) { + info!("Dispatching blocking command: {command:?}"); + COMMAND.write_message(command); +} diff --git a/studio/src/ui/mod.rs b/studio/src/ui/mod.rs index d3f0385..fa48932 100644 --- a/studio/src/ui/mod.rs +++ b/studio/src/ui/mod.rs @@ -4,6 +4,9 @@ use self::fps::FpsCounterPlugin; mod fps; +#[cfg(feature = "wasm")] +mod blocking; + #[cfg(feature = "wasm")] pub mod inspector; @@ -14,6 +17,9 @@ impl Plugin for UiLayerPlugin { app.add_plugins(FpsCounterPlugin); #[cfg(feature = "wasm")] - app.add_plugins(inspector::InspectorPlugin); + { + app.add_plugins(inspector::InspectorPlugin); + app.add_plugins(blocking::UiBlockingPlugin); + } } }