diff --git a/Cargo.toml b/Cargo.toml index 10953c9..1b1fdb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,5 +19,9 @@ path = "bin/ui-wtf.rs" name = "animation-wtf" path = "bin/animation-wtf.rs" +[[bin]] +name = "text-wtf" +path = "bin/text-wtf.rs" + [dependencies] bevy = "0.10" diff --git a/assets/fonts/BOUNCY GUM.otf b/assets/fonts/BOUNCY GUM.otf new file mode 100644 index 0000000..cf62ac9 Binary files /dev/null and b/assets/fonts/BOUNCY GUM.otf differ diff --git a/assets/fonts/Death Spirit.otf b/assets/fonts/Death Spirit.otf new file mode 100644 index 0000000..ef34465 Binary files /dev/null and b/assets/fonts/Death Spirit.otf differ diff --git a/assets/fonts/JMH Typewriter-Black.otf b/assets/fonts/JMH Typewriter-Black.otf new file mode 100644 index 0000000..1eb4171 Binary files /dev/null and b/assets/fonts/JMH Typewriter-Black.otf differ diff --git a/assets/fonts/JMH Typewriter-Bold.otf b/assets/fonts/JMH Typewriter-Bold.otf new file mode 100644 index 0000000..e791089 Binary files /dev/null and b/assets/fonts/JMH Typewriter-Bold.otf differ diff --git a/assets/fonts/JMH Typewriter-Thin.otf b/assets/fonts/JMH Typewriter-Thin.otf new file mode 100644 index 0000000..4393a2f Binary files /dev/null and b/assets/fonts/JMH Typewriter-Thin.otf differ diff --git a/assets/fonts/JMH Typewriter.otf b/assets/fonts/JMH Typewriter.otf new file mode 100644 index 0000000..5ee4685 Binary files /dev/null and b/assets/fonts/JMH Typewriter.otf differ diff --git a/assets/fonts/README.md b/assets/fonts/README.md new file mode 100644 index 0000000..7ac5755 --- /dev/null +++ b/assets/fonts/README.md @@ -0,0 +1,7 @@ +Testing fonts for personal use: + +* https://www.dafont.com/death-spirit.font +* https://www.dafont.com/bouncy-gum.font +* https://www.dafont.com/jmh-typewriter.font +* https://www.dafont.com/roseblue.font +* https://www.dafont.com/mythical-prince.font diff --git a/assets/fonts/raw/bouncy_gum.zip b/assets/fonts/raw/bouncy_gum.zip new file mode 100644 index 0000000..3fe2191 Binary files /dev/null and b/assets/fonts/raw/bouncy_gum.zip differ diff --git a/assets/fonts/raw/death_spirit.zip b/assets/fonts/raw/death_spirit.zip new file mode 100644 index 0000000..2ae7818 Binary files /dev/null and b/assets/fonts/raw/death_spirit.zip differ diff --git a/assets/fonts/raw/jmh_typewriter.zip b/assets/fonts/raw/jmh_typewriter.zip new file mode 100644 index 0000000..5af4417 Binary files /dev/null and b/assets/fonts/raw/jmh_typewriter.zip differ diff --git a/assets/fonts/raw/mythical_prince.zip b/assets/fonts/raw/mythical_prince.zip new file mode 100644 index 0000000..41014c7 Binary files /dev/null and b/assets/fonts/raw/mythical_prince.zip differ diff --git a/assets/fonts/raw/roseblue.zip b/assets/fonts/raw/roseblue.zip new file mode 100644 index 0000000..ba551f5 Binary files /dev/null and b/assets/fonts/raw/roseblue.zip differ diff --git a/bin/animation-wtf.rs b/bin/animation-wtf.rs index 61ea428..576303c 100644 --- a/bin/animation-wtf.rs +++ b/bin/animation-wtf.rs @@ -54,6 +54,7 @@ fn init(mut commands: Commands, server: Res) { .into(), ..default() }); + parent.spawn(SceneBundle { scene: server.load("models/monkey-nod.glb#Scene0"), ..default() diff --git a/bin/gltf-inspect.rs b/bin/gltf-inspect.rs index 527a748..2b268e6 100644 --- a/bin/gltf-inspect.rs +++ b/bin/gltf-inspect.rs @@ -33,8 +33,7 @@ fn main() { .add_startup_system(spawn_base_ui) .add_system(spawn_models) .add_system(spawn_ui) - .add_system(catalog_animations) - .add_system(play_animation) + .add_system(control_animation) .add_system(rotate_model) .add_system(zoom_model) .add_system(scroll) @@ -323,56 +322,78 @@ fn spawn_ui( } } -fn catalog_animations( - mut events: EventReader>, - clips: Res>, -) { - for event in events.iter() { - match event { - AssetEvent::Created { handle } => { - if let Some(clip) = clips.get(handle) { - info!("Event: {:#?}", clip.curves()); - } - } - _ => (), - } - } -} - -fn play_animation( - mut events: EventReader, +fn control_animation( + mut key_evr: EventReader, + mut active_evr: EventReader, mut players: Query<&mut AnimationPlayer>, children: Query<&Children>, models: Res, gltfs: Res>, + mut active: Local>, + mut playing: Local, + mut dirty: Local, ) { - for event in events.iter() { + for event in active_evr.iter() { match event { ManageActive(None) => { - info!("Disabling all animations"); - for mut player in players.iter_mut() { - player.stop_repeating(); - } + // world state must be updated + *dirty = true; + // Stop playing + *playing = false; + // Add this to a list of acive entities + (*active).clear(); } ManageActive(Some(entity)) => { - info!("Setting {:?} Active Animation", entity); + // world state must be updated + *dirty = true; + // Start playing + *playing = true; + // Add this to a list of acive entities + (*active).push(*entity); + } + } + } + for event in key_evr.iter() { + match event { + KeyboardInput { + key_code: Some(KeyCode::Space), + state: ButtonState::Pressed, + .. + } => { + // World state needs to be updated to deisred state + *dirty = true; + // Toggle playing + *playing = !(*playing); + } + _ => (), + } + } + // If world needs to be updated + if *dirty { + if *playing { + for entity in active.iter() { for child in children.iter_descendants(*entity) { if let Ok(mut player) = players.get_mut(child) { for gltf_handle in models.handles.iter() { if let Some(gltf) = gltfs.get(gltf_handle) { for animation_handle in gltf.animations.iter() { player.start(animation_handle.clone()).repeat(); + player.resume(); } } else { info!("Failed to get GLTF handle"); } } - } else { - info!("Failed to get active animation player"); } } } + } else { + for mut player in players.iter_mut() { + player.pause(); + } } + // Done making updates + *dirty = false; } } @@ -417,13 +438,17 @@ fn zoom_model( fn scroll( mut scroll_evr: EventReader, mut query: Query<&mut Style, With>, + active: Query>, ) { for ev in scroll_evr.iter() { - for mut s in query.iter_mut() { - s.position.top = match s.position.top { - Val::Px(current) => Val::Px(current + (ev.y * 5.0)), - _ => Val::Px(0.0), - }; + // Only scroll if scene not selected + if active.is_empty() { + for mut s in query.iter_mut() { + s.position.top = match s.position.top { + Val::Px(current) => Val::Px(current + (ev.y * 5.0)), + _ => Val::Px(0.0), + }; + } } } } diff --git a/bin/text-wtf.rs b/bin/text-wtf.rs new file mode 100644 index 0000000..d74093e --- /dev/null +++ b/bin/text-wtf.rs @@ -0,0 +1,195 @@ +use bevy::prelude::*; + +const LOREM: [&str; 5] = [ + "Ullam nostrum aut amet adipisci consequuntur quisquam nemo consequatur. Vel eum et ullam ullam aperiam earum voluptas consequuntur. Blanditiis earum voluptatem voluptas animi dolorum fuga aliquam ea.\n", + "Velit ratione consequatur modi. Dolores quo quisquam occaecati veniam maxime totam minus et. Laudantium unde optio vel. Et cumque voluptatum dolorem. Odit tempore dolores quibusdam aspernatur vitae labore occaecati. Omnis quia tempora tenetur repellat in.\n", + "Dolores perspiciatis tempore in consequuntur in minus autem. Voluptatem quas dignissimos quae ut necessitatibus illo ducimus. Quis fuga nisi non ut sunt velit.\n", + "Sit quia officia alias hic. Incidunt sed vitae optio cumque rerum corrupti perferendis enim. Adipisci necessitatibus illum vero placeat saepe aut et.\n", + "Velit perspiciatis doloribus consectetur. Doloremque ea non optio itaque. Voluptatem sint voluptatum minus.\n", +]; + +fn main() { + App::new() + .add_plugins(DefaultPlugins.set(WindowPlugin { + primary_window: Some(Window { + title: "Text WTF".into(), + resolution: (640., 480.).into(), + ..default() + }), + ..default() + })) + .add_startup_system(load_fonts) + .add_startup_system(init_ui) + .add_system(manage_buttons) + .add_system(update) + .add_system(mouse_cursor) + .run(); +} + +#[derive(Resource)] +struct Fonts(Vec>); + +#[derive(Component)] +struct Marker; + +#[derive(Component)] +struct PreviewText; + +#[derive(Component)] +struct ButtonShelf; + +#[derive(Component)] +struct FontButton(Handle); + +fn load_fonts(mut commands: Commands, server: Res) { + let handles = server + .load_folder("fonts") + .expect("Load fonts folder") + .iter() + .map(|untyped| untyped.clone().typed::()) + .collect(); + commands.insert_resource(Fonts(handles)); +} + +fn init_ui(mut commands: Commands) { + commands.spawn(Camera2dBundle { ..default() }); + + commands + .spawn(( + NodeBundle { + style: Style { + size: Size::all(Val::Percent(100.0)), + ..default() + }, + background_color: BackgroundColor(Color::BLACK), + ..default() + }, + Marker, + )) + .with_children(|parent| { + parent.spawn(( + NodeBundle { + style: Style { + flex_direction: FlexDirection::Column, + align_items: AlignItems::Center, + size: Size { + width: Val::Px(200.0), + height: Val::Undefined, + }, + align_content: AlignContent::SpaceEvenly, + ..default() + }, + background_color: BackgroundColor(Color::BLACK), + ..default() + }, + Marker, + ButtonShelf, + )); + + { + parent.spawn(( + TextBundle::from_sections(LOREM.iter().map(|§ion| TextSection { + value: section.into(), + style: TextStyle { + font_size: 50.0, + ..default() + }, + })), + Marker, + PreviewText, + )); + } + }); +} + +// Add/remove buttons from shelf with font name(s) +fn manage_buttons( + mut commands: Commands, + fonts: Res, + server: Res, + query: Query, With)>, +) { + if fonts.is_added() || fonts.is_changed() { + let root = query.get_single().expect("Fetching root UI node"); + let mut root_cmd = commands.get_entity(root).expect("Root UI node commands"); + + root_cmd.clear_children(); + root_cmd.with_children(|root| { + fonts.0.iter().for_each(|font| { + let handle_path = server + .get_handle_path(font.clone()) + .expect("Get handle path"); + let path = handle_path.path().to_str().expect("Convert path to str"); + let fname = path + .split("/") + .last() + .expect("Extracting filename") + .strip_suffix(".otf") + .expect("Stripping prefix"); + + let style = TextStyle { + font: font.clone(), + color: Color::BLACK, + font_size: 18.0, + }; + + root.spawn(( + ButtonBundle { + style: Style { + align_content: AlignContent::Center, + // size: Size { + // width: Val::Undefined, + // height: Val::Undefined, + // }, + padding: UiRect::all(Val::Px(5.0)), + ..default() + }, + ..default() + }, + FontButton(font.clone()), + Marker, + )) + .with_children(|parent| { + info!("Adding {} button", fname); + parent.spawn((TextBundle::from_section(fname, style), Marker)); + }); + }); + }); + } +} + +fn update( + mut texts: Query<&mut Text, (With, With)>, + interaction: Query<(&Interaction, &FontButton), Changed>, +) { + for (i, f) in interaction.iter() { + match (i, f) { + (Interaction::Clicked, FontButton(font)) => { + let mut text = texts.single_mut(); + *text = Text::from_sections(LOREM.iter().map(|&s| TextSection { + value: s.into(), + style: TextStyle { + font: font.clone(), + font_size: 50.0, + ..default() + }, + })); + } + _ => (), + } + } +} + +fn mouse_cursor( + mut windows: Query<&mut Window>, + interactions: Query<&Interaction, (Changed, With