From d887f49c7ba4c4aebcb1687c649de0ed86aa340f Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sun, 27 Aug 2023 11:49:33 -0700 Subject: [PATCH] Implemented text preview, sans font --- assets/monologues/a.monologue.txt | 1 + assets/monologues/b.monologue.txt | 1 + bin/editor.rs | 492 +++++++++++++++++++----------- 3 files changed, 308 insertions(+), 186 deletions(-) create mode 100644 assets/monologues/a.monologue.txt create mode 100644 assets/monologues/b.monologue.txt diff --git a/assets/monologues/a.monologue.txt b/assets/monologues/a.monologue.txt new file mode 100644 index 0000000..3fdb30d --- /dev/null +++ b/assets/monologues/a.monologue.txt @@ -0,0 +1 @@ +This is a placeholder monologue diff --git a/assets/monologues/b.monologue.txt b/assets/monologues/b.monologue.txt new file mode 100644 index 0000000..3fdb30d --- /dev/null +++ b/assets/monologues/b.monologue.txt @@ -0,0 +1 @@ +This is a placeholder monologue diff --git a/bin/editor.rs b/bin/editor.rs index a4f22cc..075a367 100644 --- a/bin/editor.rs +++ b/bin/editor.rs @@ -61,7 +61,7 @@ fn main() { .init_asset_loader::() .add_event::>() .add_event::>() - .add_systems(Startup, (initialize_ui, welcome_message)) + .add_systems(Startup, (initialize_ui, init_texts_ui, welcome_message)) .add_systems( Update, ( @@ -80,6 +80,7 @@ fn main() { manage_camera, play_animation, play_audio, + show_preview_text, ), ) .run(); @@ -184,6 +185,11 @@ fn initialize_ui(mut commands: Commands) { parent, ui::Select::Single, )); + content_containers.push(spawn_tab_container::( + "Monologue", + parent, + ui::Select::Single, + )); content_containers.push(spawn_tab_container::( "Audio", parent, @@ -265,7 +271,7 @@ fn initialize_ui(mut commands: Commands) { justify_content: JustifyContent::SpaceBetween, ..default() }, - background_color: Color::ALICE_BLUE.into(), + background_color: Color::WHITE.into(), border_color: Color::BLACK.into(), ..default() }, @@ -365,74 +371,65 @@ mod audio { current: Query<(Entity, &ui::TargetAsset)>, server: Res, ) { - events - .iter() - .filter(|&event| match event { - AssetEvent::Created { handle } - | AssetEvent::Removed { handle } - | AssetEvent::Modified { handle } => { - has_extensions(&server, handle.clone(), &["ogg"]) - } - }) - .for_each(|event| match event { - AssetEvent::Created { handle } => { - info!("Asset created! {:?}", event); - let id = create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - None, - ); - commands.entity(id).insert(AudioSourceBundle { - source: handle.clone(), - settings: PlaybackSettings { - mode: PlaybackMode::Loop, - paused: true, - ..default() - }, - }); - } - AssetEvent::Removed { handle } => { - info!("Asset removed! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - } - AssetEvent::Modified { handle } => { - info!("Asset modified! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - let id = create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - None, - ); - commands.entity(id).insert(AudioSourceBundle { - source: handle.clone(), - settings: PlaybackSettings { - mode: PlaybackMode::Loop, - paused: true, - ..default() - }, - }); - } - }); + events.iter().for_each(|event| match event { + AssetEvent::Created { handle } => { + info!("Asset created! {:?}", event); + let id = create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + commands.entity(id).insert(AudioSourceBundle { + source: handle.clone(), + settings: PlaybackSettings { + mode: PlaybackMode::Loop, + paused: true, + ..default() + }, + }); + } + AssetEvent::Removed { handle } => { + info!("Asset removed! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + } + AssetEvent::Modified { handle } => { + info!("Asset modified! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + let id = create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + commands.entity(id).insert(AudioSourceBundle { + source: handle.clone(), + settings: PlaybackSettings { + mode: PlaybackMode::Loop, + paused: true, + ..default() + }, + }); + } + }); } pub fn play_audio( @@ -579,58 +576,49 @@ mod gltf { current: Query<(Entity, &ui::TargetAsset)>, server: Res, ) { - events - .iter() - .filter(|&event| match event { - AssetEvent::Created { handle } - | AssetEvent::Removed { handle } - | AssetEvent::Modified { handle } => { - has_extensions(&server, handle.clone(), &["gltf", "glb"]) - } - }) - .for_each(|event| match event { - AssetEvent::Created { handle } => { - info!("Asset created! {:?}", event); - create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - None, - ); - } - AssetEvent::Removed { handle } => { - info!("Asset removed! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - } - AssetEvent::Modified { handle } => { - info!("Asset modified! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - None, - ); - } - }); + events.iter().for_each(|event| match event { + AssetEvent::Created { handle } => { + info!("Asset created! {:?}", event); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + } + AssetEvent::Removed { handle } => { + info!("Asset removed! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + } + AssetEvent::Modified { handle } => { + info!("Asset modified! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + } + }); } pub fn manage_active_gltf( @@ -902,65 +890,59 @@ mod fonts { current: Query<(Entity, &ui::TargetAsset)>, server: Res, ) { - events - .iter() - .filter(|&event| match event { - AssetEvent::Created { handle } - | AssetEvent::Removed { handle } - | AssetEvent::Modified { handle } => { - has_extensions(&server, handle.clone(), &["ttf", "otf"]) - } - }) - .for_each(|event| match event { - AssetEvent::Created { handle } => { - info!("Asset created! {:?}", event); - create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - Some(handle.clone()), - ); - } - AssetEvent::Removed { handle } => { - info!("Asset removed! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - } - AssetEvent::Modified { handle } => { - info!("Asset modified! {:?}", event); - destroy_asset_button( - ¤t, - &mut commands, - &ui::TargetAsset { - handle: handle.clone(), - }, - ); - create_asset_button( - &widget, - &mut commands, - ui::TargetAsset { - handle: handle.clone(), - }, - get_asset_name(&server, handle.clone()), - Some(handle.clone()), - ); - } - }); + events.iter().for_each(|event| match event { + AssetEvent::Created { handle } => { + info!("Asset created! {:?}", event); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + Some(handle.clone()), + ); + } + AssetEvent::Removed { handle } => { + info!("Asset removed! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + } + AssetEvent::Modified { handle } => { + info!("Asset modified! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + Some(handle.clone()), + ); + } + }); } } use monologues::*; mod monologues { use super::*; - use bevy::reflect::{TypePath, TypeUuid}; + use bevy::{ + reflect::{TypePath, TypeUuid}, + ui::FocusPolicy, + }; use serde::Deserialize; #[derive(Debug, Component, Default)] @@ -972,6 +954,12 @@ mod monologues { text: String, } + #[derive(Debug, Component)] + pub struct MonologueModal; + + #[derive(Debug, Component)] + pub struct MonologueContainer; + #[derive(Default)] pub struct MonologueLoader; @@ -982,29 +970,161 @@ mod monologues { load_context: &'a mut LoadContext, ) -> BoxedFuture<'a, Result<(), bevy::asset::Error>> { Box::pin(async move { - load_context.set_default_asset(LoadedAsset::new( - String::from_utf8(bytes.to_vec()).expect("Convert bytes to String"), - )); + let asset = Monologue { + text: String::from_utf8(bytes.to_vec())?, + }; + load_context.set_default_asset(LoadedAsset::new(asset)); Ok(()) }) } fn extensions(&self) -> &[&str] { - &[".monologue.txt"] + &["monologue.txt"] } } + pub fn init_texts_ui(mut commands: Commands) { + commands.spawn(( + NodeBundle { + style: Style { + width: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..default() + }, + focus_policy: FocusPolicy::Pass, + ..default() + }, + MonologueContainer, + )); + } + // TODO: Load .txt files for monologues pub fn texts_ui( mut events: EventReader>, - mut _commands: Commands, - _widget: Query>, - _current: Query<(Entity, &ui::TargetAsset)>, - _server: Res, + mut commands: Commands, + widget: Query>, + current: Query<(Entity, &ui::TargetAsset)>, + server: Res, ) { - events.iter().for_each(|_event| { - info!("Loading monologue"); - }) + events.iter().for_each(|event| match event { + AssetEvent::Created { handle } => { + info!("Monologue created! {:?}", event); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + } + AssetEvent::Removed { handle } => { + info!("Monologue removed! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + } + AssetEvent::Modified { handle } => { + info!("Monologue modified! {:?}", event); + destroy_asset_button( + ¤t, + &mut commands, + &ui::TargetAsset { + handle: handle.clone(), + }, + ); + create_asset_button( + &widget, + &mut commands, + ui::TargetAsset { + handle: handle.clone(), + }, + get_asset_name(&server, handle.clone()), + None, + ); + } + }); + } + + // TODO(BUG): Better handle hide/close monologue + pub fn show_preview_text( + show: Query, Added)>, + mut removed: RemovedComponents, + monologue_handles: Query<&ui::TargetAsset>, + monologues: Res>, + container: Query>, + mut commands: Commands, + ) { + removed + .iter() + .filter_map(|entity| monologue_handles.get(entity).ok()) + .for_each(|_| { + commands.entity(container.single()).despawn_descendants(); + }); + show.iter() + .filter_map(|entity| monologue_handles.get(entity).ok()) + .for_each(|ui::TargetAsset { handle }| { + let monologue = monologues.get(handle).expect("Preview loaded monologue"); + commands + .entity(container.single()) + .despawn_descendants() + .with_children(|parent| { + parent + .spawn(NodeBundle { + style: Style { + max_width: Val::Percent(50.0), + padding: UiRect::all(Val::Px(1.0)), + margin: UiRect::all(Val::Px(1.0)), + border: UiRect::all(Val::Px(1.0)), + flex_direction: FlexDirection::Column, + ..default() + }, + + background_color: Color::WHITE.into(), + border_color: Color::BLACK.into(), + ..default() + }) + .with_children(|parent| { + parent.spawn(( + NodeBundle { + style: Style { + padding: UiRect::all(Val::Px(1.0)), + margin: UiRect::all(Val::Px(1.0)), + border: UiRect::all(Val::Px(1.0)), + flex_direction: FlexDirection::Row, + align_items: AlignItems::Center, + justify_content: JustifyContent::SpaceBetween, + ..default() + }, + background_color: Color::VIOLET.into(), + border_color: Color::BLACK.into(), + ..default() + }, + ui::Title { + text: "Monologue".into(), + ..default() + }, + ui::Close { + target: parent.parent_entity(), + }, + ui::Sorting(0), + )); + parent.spawn(TextBundle::from_section( + monologue.text.clone(), + TextStyle { + color: Color::BLACK.into(), + ..default() + }, + )); + }); + }); + }) } }