very basic text inspection program

main
Elijah Voigt 2 years ago
parent 95c6eae828
commit 5abb6b2e83

@ -19,5 +19,9 @@ path = "bin/ui-wtf.rs"
name = "animation-wtf" name = "animation-wtf"
path = "bin/animation-wtf.rs" path = "bin/animation-wtf.rs"
[[bin]]
name = "text-wtf"
path = "bin/text-wtf.rs"
[dependencies] [dependencies]
bevy = "0.10" bevy = "0.10"

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -54,6 +54,7 @@ fn init(mut commands: Commands, server: Res<AssetServer>) {
.into(), .into(),
..default() ..default()
}); });
parent.spawn(SceneBundle { parent.spawn(SceneBundle {
scene: server.load("models/monkey-nod.glb#Scene0"), scene: server.load("models/monkey-nod.glb#Scene0"),
..default() ..default()

@ -33,8 +33,7 @@ fn main() {
.add_startup_system(spawn_base_ui) .add_startup_system(spawn_base_ui)
.add_system(spawn_models) .add_system(spawn_models)
.add_system(spawn_ui) .add_system(spawn_ui)
.add_system(catalog_animations) .add_system(control_animation)
.add_system(play_animation)
.add_system(rotate_model) .add_system(rotate_model)
.add_system(zoom_model) .add_system(zoom_model)
.add_system(scroll) .add_system(scroll)
@ -323,57 +322,79 @@ fn spawn_ui(
} }
} }
fn catalog_animations( fn control_animation(
mut events: EventReader<AssetEvent<AnimationClip>>, mut key_evr: EventReader<KeyboardInput>,
clips: Res<Assets<AnimationClip>>, mut active_evr: EventReader<ManageActive>,
) {
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<ManageActive>,
mut players: Query<&mut AnimationPlayer>, mut players: Query<&mut AnimationPlayer>,
children: Query<&Children>, children: Query<&Children>,
models: Res<Models>, models: Res<Models>,
gltfs: Res<Assets<Gltf>>, gltfs: Res<Assets<Gltf>>,
mut active: Local<Vec<Entity>>,
mut playing: Local<bool>,
mut dirty: Local<bool>,
) { ) {
for event in events.iter() { for event in active_evr.iter() {
match event { match event {
ManageActive(None) => { ManageActive(None) => {
info!("Disabling all animations"); // world state must be updated
for mut player in players.iter_mut() { *dirty = true;
player.stop_repeating(); // Stop playing
} *playing = false;
// Add this to a list of acive entities
(*active).clear();
} }
ManageActive(Some(entity)) => { 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) { for child in children.iter_descendants(*entity) {
if let Ok(mut player) = players.get_mut(child) { if let Ok(mut player) = players.get_mut(child) {
for gltf_handle in models.handles.iter() { for gltf_handle in models.handles.iter() {
if let Some(gltf) = gltfs.get(gltf_handle) { if let Some(gltf) = gltfs.get(gltf_handle) {
for animation_handle in gltf.animations.iter() { for animation_handle in gltf.animations.iter() {
player.start(animation_handle.clone()).repeat(); player.start(animation_handle.clone()).repeat();
player.resume();
} }
} else { } else {
info!("Failed to get GLTF handle"); 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,8 +438,11 @@ fn zoom_model(
fn scroll( fn scroll(
mut scroll_evr: EventReader<MouseWheel>, mut scroll_evr: EventReader<MouseWheel>,
mut query: Query<&mut Style, With<ScrollingList>>, mut query: Query<&mut Style, With<ScrollingList>>,
active: Query<Entity, With<Active>>,
) { ) {
for ev in scroll_evr.iter() { for ev in scroll_evr.iter() {
// Only scroll if scene not selected
if active.is_empty() {
for mut s in query.iter_mut() { for mut s in query.iter_mut() {
s.position.top = match s.position.top { s.position.top = match s.position.top {
Val::Px(current) => Val::Px(current + (ev.y * 5.0)), Val::Px(current) => Val::Px(current + (ev.y * 5.0)),
@ -426,6 +450,7 @@ fn scroll(
}; };
} }
} }
}
} }
/// ///

@ -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<Handle<Font>>);
#[derive(Component)]
struct Marker;
#[derive(Component)]
struct PreviewText;
#[derive(Component)]
struct ButtonShelf;
#[derive(Component)]
struct FontButton(Handle<Font>);
fn load_fonts(mut commands: Commands, server: Res<AssetServer>) {
let handles = server
.load_folder("fonts")
.expect("Load fonts folder")
.iter()
.map(|untyped| untyped.clone().typed::<Font>())
.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(|&section| 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<Fonts>,
server: Res<AssetServer>,
query: Query<Entity, (With<Marker>, With<ButtonShelf>)>,
) {
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<Marker>, With<PreviewText>)>,
interaction: Query<(&Interaction, &FontButton), Changed<Interaction>>,
) {
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<Interaction>, With<Button>)>,
) {
for interaction in interactions.iter() {
let mut window = windows.single_mut();
window.cursor.icon = match interaction {
Interaction::Hovered | Interaction::Clicked => CursorIcon::Hand,
Interaction::None => CursorIcon::Arrow,
}
}
}
Loading…
Cancel
Save