add a default font (#8445)

# Objective

- Have a default font

## Solution

- Add a font based on FiraMono containing only ASCII characters and use
it as the default font
- It is behind a feature `default_font` enabled by default
- I also updated examples to use it, but not UI examples to still show
how to use a custom font

---

## Changelog

* If you display text without using the default handle provided by
`TextStyle`, the text will be displayed
This commit is contained in:
François 2023-04-22 00:30:18 +02:00 committed by GitHub
parent ddefc246b2
commit e0e5f3acd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 90 additions and 124 deletions

View file

@ -52,6 +52,7 @@ default = [
"bevy_gizmos", "bevy_gizmos",
"android_shared_stdcxx", "android_shared_stdcxx",
"tonemapping_luts", "tonemapping_luts",
"default_font",
] ]
# Force dynamic linking, which improves iterative compile times # Force dynamic linking, which improves iterative compile times
@ -225,6 +226,9 @@ accesskit_unix = ["bevy_internal/accesskit_unix"]
# Enable assertions to check the validity of parameters passed to glam # Enable assertions to check the validity of parameters passed to glam
glam_assert = ["bevy_internal/glam_assert"] glam_assert = ["bevy_internal/glam_assert"]
# Include a default font, containing only ASCII characters, at the cost of a 20kB binary size increase
default_font = ["bevy_internal/default_font"]
[dependencies] [dependencies]
bevy_dylib = { path = "crates/bevy_dylib", version = "0.11.0-dev", default-features = false, optional = true } bevy_dylib = { path = "crates/bevy_dylib", version = "0.11.0-dev", default-features = false, optional = true }
bevy_internal = { path = "crates/bevy_internal", version = "0.11.0-dev", default-features = false } bevy_internal = { path = "crates/bevy_internal", version = "0.11.0-dev", default-features = false }

View file

@ -97,6 +97,8 @@ bevy_render = ["dep:bevy_render", "bevy_scene?/bevy_render"]
# Enable assertions to check the validity of parameters passed to glam # Enable assertions to check the validity of parameters passed to glam
glam_assert = ["bevy_math/glam_assert"] glam_assert = ["bevy_math/glam_assert"]
default_font = ["bevy_text?/default_font"]
[dependencies] [dependencies]
# bevy # bevy
bevy_a11y = { path = "../bevy_a11y", version = "0.11.0-dev" } bevy_a11y = { path = "../bevy_a11y", version = "0.11.0-dev" }

View file

@ -10,6 +10,7 @@ keywords = ["bevy"]
[features] [features]
subpixel_glyph_atlas = [] subpixel_glyph_atlas = []
default_font = []
[dependencies] [dependencies]
# bevy # bevy

Binary file not shown.

View file

@ -26,8 +26,11 @@ pub mod prelude {
} }
use bevy_app::prelude::*; use bevy_app::prelude::*;
use bevy_asset::AddAsset; #[cfg(feature = "default_font")]
use bevy_asset::load_internal_binary_asset;
use bevy_asset::{AddAsset, HandleUntyped};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_reflect::TypeUuid;
use bevy_render::{camera::CameraUpdateSystem, ExtractSchedule, RenderApp}; use bevy_render::{camera::CameraUpdateSystem, ExtractSchedule, RenderApp};
use bevy_sprite::SpriteSystem; use bevy_sprite::SpriteSystem;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -67,6 +70,9 @@ pub enum YAxisOrientation {
BottomToTop, BottomToTop,
} }
pub const DEFAULT_FONT_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Font::TYPE_UUID, 1491772431825224042);
impl Plugin for TextPlugin { impl Plugin for TextPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_asset::<Font>() app.add_asset::<Font>()
@ -98,5 +104,13 @@ impl Plugin for TextPlugin {
extract_text2d_sprite.after(SpriteSystem::ExtractSprites), extract_text2d_sprite.after(SpriteSystem::ExtractSprites),
); );
} }
#[cfg(feature = "default_font")]
load_internal_binary_asset!(
app,
DEFAULT_FONT_HANDLE,
"FiraMono-subset.ttf",
|bytes: &[u8]| { Font::try_from_bytes(bytes.to_vec()).unwrap() }
);
} }
} }

View file

@ -6,6 +6,8 @@ use bevy_utils::default;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::Font; use crate::Font;
#[cfg(feature = "default_font")]
use crate::DEFAULT_FONT_HANDLE;
#[derive(Component, Debug, Clone, Reflect)] #[derive(Component, Debug, Clone, Reflect)]
#[reflect(Component, Default)] #[reflect(Component, Default)]
@ -167,7 +169,7 @@ pub struct TextStyle {
impl Default for TextStyle { impl Default for TextStyle {
fn default() -> Self { fn default() -> Self {
Self { Self {
font: Default::default(), font: DEFAULT_FONT_HANDLE.typed(),
font_size: 12.0, font_size: 12.0,
color: Color::WHITE, color: Color::WHITE,
} }

View file

@ -27,6 +27,7 @@ The default feature set enables most of the expected features of a game engine,
|bevy_text|Provides text functionality| |bevy_text|Provides text functionality|
|bevy_ui|A custom ECS-driven UI framework| |bevy_ui|A custom ECS-driven UI framework|
|bevy_winit|winit window and input backend| |bevy_winit|winit window and input backend|
|default_font|Include a default font, containing only ASCII characters, at the cost of a 20kB binary size increase|
|filesystem_watcher|Enable watching file system for asset hot reload| |filesystem_watcher|Enable watching file system for asset hot reload|
|hdr|HDR image format support| |hdr|HDR image format support|
|ktx2|KTX2 compressed texture support| |ktx2|KTX2 compressed texture support|

View file

@ -72,9 +72,9 @@ fn setup(
TextBundle::from_section( TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -15,7 +15,6 @@ fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) { ) {
commands.spawn(Camera3dBundle { commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y), transform: Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
@ -48,9 +47,9 @@ fn setup(
commands.spawn(TextBundle::from_section( commands.spawn(TextBundle::from_section(
"Press 't' to toggle drawing gizmos on top of everything else in the scene", "Press 't' to toggle drawing gizmos on top of everything else in the scene",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 24., font_size: 24.,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
)); ));
} }

View file

@ -329,9 +329,9 @@ fn setup(
TextBundle::from_section( TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 20.0, font_size: 20.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -93,13 +93,13 @@ fn setup_terrain_scene(
)); ));
} }
fn setup_instructions(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup_instructions(mut commands: Commands) {
commands.spawn((TextBundle::from_section( commands.spawn((TextBundle::from_section(
"Press Spacebar to Toggle Atmospheric Fog.\nPress S to Toggle Directional Light Fog Influence.", "Press Spacebar to Toggle Atmospheric Fog.\nPress S to Toggle Directional Light Fog Influence.",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 15.0, font_size: 15.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -34,7 +34,6 @@ fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) { ) {
let base_color = Color::rgba(0.9, 0.2, 0.3, 1.0); let base_color = Color::rgba(0.9, 0.2, 0.3, 1.0);
let icosphere_mesh = meshes.add( let icosphere_mesh = meshes.add(
@ -186,15 +185,15 @@ fn setup(
// Controls Text // Controls Text
let text_style = TextStyle { let text_style = TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}; };
let label_text_style = TextStyle { let label_text_style = TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 25.0, font_size: 25.0,
color: Color::ORANGE, color: Color::ORANGE,
..default()
}; };
commands.spawn( commands.spawn(

View file

@ -25,7 +25,6 @@ fn setup_scene(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) { ) {
commands.spawn(( commands.spawn((
Camera3dBundle { Camera3dBundle {
@ -96,9 +95,9 @@ fn setup_scene(
TextBundle::from_section( TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -137,13 +137,13 @@ fn setup_pyramid_scene(
}); });
} }
fn setup_instructions(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup_instructions(mut commands: Commands) {
commands.spawn((TextBundle::from_section( commands.spawn((TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 15.0, font_size: 15.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -315,9 +315,9 @@ fn setup(
commands.spawn(background_cube_bundle(Vec3::new(0., 0., -45.))); commands.spawn(background_cube_bundle(Vec3::new(0., 0., -45.)));
let style = TextStyle { let style = TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}; };
commands.spawn( commands.spawn(

View file

@ -78,9 +78,9 @@ fn setup(
TextBundle::from_section( TextBundle::from_section(
"Perceptual Roughness", "Perceptual Roughness",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 36.0, font_size: 36.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {
@ -95,9 +95,9 @@ fn setup(
text: Text::from_section( text: Text::from_section(
"Metallic", "Metallic",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 36.0, font_size: 36.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
), ),
style: Style { style: Style {
@ -117,9 +117,9 @@ fn setup(
TextBundle::from_section( TextBundle::from_section(
"Loading Environment Map...", "Loading Environment Map...",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 36.0, font_size: 36.0,
color: Color::RED, color: Color::RED,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -75,9 +75,9 @@ fn setup(
TextBundle::from_section( TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {
@ -243,7 +243,6 @@ fn setup_image_viewer_scene(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
camera_transform: Res<CameraTransform>, camera_transform: Res<CameraTransform>,
asset_server: Res<AssetServer>,
) { ) {
let mut transform = camera_transform.0; let mut transform = camera_transform.0;
transform.translation += transform.forward(); transform.translation += transform.forward();
@ -273,9 +272,9 @@ fn setup_image_viewer_scene(
TextBundle::from_section( TextBundle::from_section(
"Drag and drop an HDR or EXR file", "Drag and drop an HDR or EXR file",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 36.0, font_size: 36.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}, },
) )
.with_text_alignment(TextAlignment::Center) .with_text_alignment(TextAlignment::Center)

View file

@ -19,10 +19,7 @@ fn main() {
struct StreamReceiver(Receiver<u32>); struct StreamReceiver(Receiver<u32>);
struct StreamEvent(u32); struct StreamEvent(u32);
#[derive(Resource, Deref)] fn setup(mut commands: Commands) {
struct LoadedFont(Handle<Font>);
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
let (tx, rx) = bounded::<u32>(10); let (tx, rx) = bounded::<u32>(10);
@ -40,7 +37,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
}); });
commands.insert_resource(StreamReceiver(rx)); commands.insert_resource(StreamReceiver(rx));
commands.insert_resource(LoadedFont(asset_server.load("fonts/FiraSans-Bold.ttf")));
} }
// This system reads from the receiver and sends events to Bevy // This system reads from the receiver and sends events to Bevy
@ -50,15 +46,11 @@ fn read_stream(receiver: Res<StreamReceiver>, mut events: EventWriter<StreamEven
} }
} }
fn spawn_text( fn spawn_text(mut commands: Commands, mut reader: EventReader<StreamEvent>) {
mut commands: Commands,
mut reader: EventReader<StreamEvent>,
loaded_font: Res<LoadedFont>,
) {
let text_style = TextStyle { let text_style = TextStyle {
font: loaded_font.clone(),
font_size: 20.0, font_size: 20.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}; };
for (per_frame, event) in reader.iter().enumerate() { for (per_frame, event) in reader.iter().enumerate() {

View file

@ -63,7 +63,7 @@ struct AppleCount;
struct OrangeCount; struct OrangeCount;
// Setup the counters in the UI. // Setup the counters in the UI.
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
commands commands
@ -82,9 +82,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
TextBundle::from_section( TextBundle::from_section(
"Apple: nothing counted yet".to_string(), "Apple: nothing counted yet".to_string(),
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 80.0, font_size: 80.0,
color: Color::ORANGE, color: Color::ORANGE,
..default()
}, },
), ),
AppleCount, AppleCount,
@ -93,9 +93,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
TextBundle::from_section( TextBundle::from_section(
"Orange: nothing counted yet".to_string(), "Orange: nothing counted yet".to_string(),
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 80.0, font_size: 80.0,
color: Color::ORANGE, color: Color::ORANGE,
..default()
}, },
), ),
OrangeCount, OrangeCount,

View file

@ -48,7 +48,7 @@ fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
} }
fn setup_menu(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup_menu(mut commands: Commands) {
let button_entity = commands let button_entity = commands
.spawn(NodeBundle { .spawn(NodeBundle {
style: Style { style: Style {
@ -78,9 +78,9 @@ fn setup_menu(mut commands: Commands, asset_server: Res<AssetServer>) {
parent.spawn(TextBundle::from_section( parent.spawn(TextBundle::from_section(
"Play", "Play",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color: Color::rgb(0.9, 0.9, 0.9), color: Color::rgb(0.9, 0.9, 0.9),
..default()
}, },
)); ));
}); });

View file

@ -168,9 +168,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
TextBundle::from_section( TextBundle::from_section(
"Score:", "Score:",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color: Color::rgb(0.5, 0.5, 1.0), color: Color::rgb(0.5, 0.5, 1.0),
..default()
}, },
) )
.with_style(Style { .with_style(Style {
@ -384,7 +384,7 @@ fn gameover_keyboard(
} }
// display the number of cake eaten before losing // display the number of cake eaten before losing
fn display_score(mut commands: Commands, asset_server: Res<AssetServer>, game: Res<Game>) { fn display_score(mut commands: Commands, game: Res<Game>) {
commands commands
.spawn(NodeBundle { .spawn(NodeBundle {
style: Style { style: Style {
@ -399,9 +399,9 @@ fn display_score(mut commands: Commands, asset_server: Res<AssetServer>, game: R
parent.spawn(TextBundle::from_section( parent.spawn(TextBundle::from_section(
format!("Cake eaten: {}", game.cake_eaten), format!("Cake eaten: {}", game.cake_eaten),
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 80.0, font_size: 80.0,
color: Color::rgb(0.5, 0.5, 1.0), color: Color::rgb(0.5, 0.5, 1.0),
..default()
}, },
)); ));
}); });

View file

@ -223,15 +223,15 @@ fn setup(
TextSection::new( TextSection::new(
"Score: ", "Score: ",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: SCOREBOARD_FONT_SIZE, font_size: SCOREBOARD_FONT_SIZE,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}, },
), ),
TextSection::from_style(TextStyle { TextSection::from_style(TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: SCOREBOARD_FONT_SIZE, font_size: SCOREBOARD_FONT_SIZE,
color: SCORE_COLOR, color: SCORE_COLOR,
..default()
}), }),
]) ])
.with_style(Style { .with_style(Style {

View file

@ -145,12 +145,9 @@ mod game {
fn game_setup( fn game_setup(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>,
display_quality: Res<DisplayQuality>, display_quality: Res<DisplayQuality>,
volume: Res<Volume>, volume: Res<Volume>,
) { ) {
let font = asset_server.load("fonts/FiraSans-Bold.ttf");
commands commands
.spawn(( .spawn((
NodeBundle { NodeBundle {
@ -187,9 +184,9 @@ mod game {
TextBundle::from_section( TextBundle::from_section(
"Will be back to the menu shortly...", "Will be back to the menu shortly...",
TextStyle { TextStyle {
font: font.clone(),
font_size: 80.0, font_size: 80.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}, },
) )
.with_style(Style { .with_style(Style {
@ -202,25 +199,25 @@ mod game {
TextSection::new( TextSection::new(
format!("quality: {:?}", *display_quality), format!("quality: {:?}", *display_quality),
TextStyle { TextStyle {
font: font.clone(),
font_size: 60.0, font_size: 60.0,
color: Color::BLUE, color: Color::BLUE,
..default()
}, },
), ),
TextSection::new( TextSection::new(
" - ", " - ",
TextStyle { TextStyle {
font: font.clone(),
font_size: 60.0, font_size: 60.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}, },
), ),
TextSection::new( TextSection::new(
format!("volume: {:?}", *volume), format!("volume: {:?}", *volume),
TextStyle { TextStyle {
font: font.clone(),
font_size: 60.0, font_size: 60.0,
color: Color::GREEN, color: Color::GREEN,
..default()
}, },
), ),
]) ])
@ -398,7 +395,6 @@ mod menu {
} }
fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let font = asset_server.load("fonts/FiraSans-Bold.ttf");
// Common style for all buttons on the screen // Common style for all buttons on the screen
let button_style = Style { let button_style = Style {
size: Size::new(Val::Px(250.0), Val::Px(65.0)), size: Size::new(Val::Px(250.0), Val::Px(65.0)),
@ -417,9 +413,9 @@ mod menu {
..default() ..default()
}; };
let button_text_style = TextStyle { let button_text_style = TextStyle {
font: font.clone(),
font_size: 40.0, font_size: 40.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}; };
commands commands
@ -452,9 +448,9 @@ mod menu {
TextBundle::from_section( TextBundle::from_section(
"Bevy Game Menu UI", "Bevy Game Menu UI",
TextStyle { TextStyle {
font: font.clone(),
font_size: 80.0, font_size: 80.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}, },
) )
.with_style(Style { .with_style(Style {
@ -531,7 +527,7 @@ mod menu {
}); });
} }
fn settings_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn settings_menu_setup(mut commands: Commands) {
let button_style = Style { let button_style = Style {
size: Size::new(Val::Px(200.0), Val::Px(65.0)), size: Size::new(Val::Px(200.0), Val::Px(65.0)),
margin: UiRect::all(Val::Px(20.0)), margin: UiRect::all(Val::Px(20.0)),
@ -541,9 +537,9 @@ mod menu {
}; };
let button_text_style = TextStyle { let button_text_style = TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}; };
commands commands
@ -596,11 +592,7 @@ mod menu {
}); });
} }
fn display_settings_menu_setup( fn display_settings_menu_setup(mut commands: Commands, display_quality: Res<DisplayQuality>) {
mut commands: Commands,
asset_server: Res<AssetServer>,
display_quality: Res<DisplayQuality>,
) {
let button_style = Style { let button_style = Style {
size: Size::new(Val::Px(200.0), Val::Px(65.0)), size: Size::new(Val::Px(200.0), Val::Px(65.0)),
margin: UiRect::all(Val::Px(20.0)), margin: UiRect::all(Val::Px(20.0)),
@ -609,9 +601,9 @@ mod menu {
..default() ..default()
}; };
let button_text_style = TextStyle { let button_text_style = TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}; };
commands commands
@ -698,11 +690,7 @@ mod menu {
}); });
} }
fn sound_settings_menu_setup( fn sound_settings_menu_setup(mut commands: Commands, volume: Res<Volume>) {
mut commands: Commands,
asset_server: Res<AssetServer>,
volume: Res<Volume>,
) {
let button_style = Style { let button_style = Style {
size: Size::new(Val::Px(200.0), Val::Px(65.0)), size: Size::new(Val::Px(200.0), Val::Px(65.0)),
margin: UiRect::all(Val::Px(20.0)), margin: UiRect::all(Val::Px(20.0)),
@ -711,9 +699,9 @@ mod menu {
..default() ..default()
}; };
let button_text_style = TextStyle { let button_text_style = TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}; };
commands commands

View file

@ -55,7 +55,6 @@ fn setup_scene(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) { ) {
// plane // plane
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
@ -122,9 +121,9 @@ fn setup_scene(
TextBundle::from_section( TextBundle::from_section(
"Test Button", "Test Button",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 30.0, font_size: 30.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}, },
) )
.with_text_alignment(TextAlignment::Center), .with_text_alignment(TextAlignment::Center),

View file

@ -140,15 +140,15 @@ fn save_scene_system(world: &mut World) {
// This is only necessary for the info message in the UI. See examples/ui/text.rs for a standalone // This is only necessary for the info message in the UI. See examples/ui/text.rs for a standalone
// text example. // text example.
fn infotext_system(mut commands: Commands, asset_server: Res<AssetServer>) { fn infotext_system(mut commands: Commands) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
commands.spawn( commands.spawn(
TextBundle::from_section( TextBundle::from_section(
"Nothing to see in this window! Check the console output!", "Nothing to see in this window! Check the console output!",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -126,9 +126,9 @@ fn setup(
}); });
let style = TextStyle { let style = TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 18.0, font_size: 18.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}; };
commands.spawn( commands.spawn(

View file

@ -103,9 +103,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
TextSection::new( TextSection::new(
value, value,
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 40.0, font_size: 40.0,
color, color,
..default()
}, },
) )
}; };

View file

@ -32,7 +32,6 @@ fn main() {
})) }))
.add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_plugin(LogDiagnosticsPlugin::default()) .add_plugin(LogDiagnosticsPlugin::default())
.init_resource::<UiFont>()
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, button_system); .add_systems(Update, button_system);
@ -69,17 +68,7 @@ fn button_system(
} }
} }
#[derive(Resource)] fn setup(mut commands: Commands) {
struct UiFont(Handle<Font>);
impl FromWorld for UiFont {
fn from_world(world: &mut World) -> Self {
let asset_server = world.resource::<AssetServer>();
UiFont(asset_server.load("fonts/FiraSans-Bold.ttf"))
}
}
fn setup(mut commands: Commands, font: Res<UiFont>) {
let count = ROW_COLUMN_COUNT; let count = ROW_COLUMN_COUNT;
let count_f = count as f32; let count_f = count as f32;
let as_rainbow = |i: usize| Color::hsl((i as f32 / count_f) * 360.0, 0.9, 0.8); let as_rainbow = |i: usize| Color::hsl((i as f32 / count_f) * 360.0, 0.9, 0.8);
@ -97,15 +86,7 @@ fn setup(mut commands: Commands, font: Res<UiFont>) {
for i in 0..count { for i in 0..count {
for j in 0..count { for j in 0..count {
let color = as_rainbow(j % i.max(1)).into(); let color = as_rainbow(j % i.max(1)).into();
spawn_button( spawn_button(commands, color, count_f, i, j, spawn_text);
commands,
font.0.clone_weak(),
color,
count_f,
i,
j,
spawn_text,
);
} }
} }
}); });
@ -113,7 +94,6 @@ fn setup(mut commands: Commands, font: Res<UiFont>) {
fn spawn_button( fn spawn_button(
commands: &mut ChildBuilder, commands: &mut ChildBuilder,
font: Handle<Font>,
color: BackgroundColor, color: BackgroundColor,
total: f32, total: f32,
i: usize, i: usize,
@ -142,9 +122,9 @@ fn spawn_button(
commands.spawn(TextBundle::from_section( commands.spawn(TextBundle::from_section(
format!("{i}, {j}"), format!("{i}, {j}"),
TextStyle { TextStyle {
font,
font_size: FONT_SIZE, font_size: FONT_SIZE,
color: Color::rgb(0.2, 0.2, 0.2), color: Color::rgb(0.2, 0.2, 0.2),
..default()
}, },
)); ));
}); });

View file

@ -73,7 +73,7 @@ fn system(config: Res<Config>, time: Res<Time>, mut draw: Gizmos) {
} }
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands) {
warn!(include_str!("warning_string.txt")); warn!(include_str!("warning_string.txt"));
commands.spawn(Camera3dBundle { commands.spawn(Camera3dBundle {
@ -84,7 +84,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(TextBundle::from_section( commands.spawn(TextBundle::from_section(
"", "",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 30., font_size: 30.,
..default() ..default()
}, },

View file

@ -24,15 +24,15 @@ fn main() {
.run(); .run();
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
let mut text = Text { let mut text = Text {
sections: vec![TextSection { sections: vec![TextSection {
value: "0123456789".repeat(10_000), value: "0123456789".repeat(10_000),
style: TextStyle { style: TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 4., font_size: 4.,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
}], }],
alignment: TextAlignment::Left, alignment: TextAlignment::Left,

View file

@ -81,14 +81,6 @@ impl FromWorld for ButtonMeshes {
} }
} }
} }
#[derive(Resource, Deref)]
struct FontHandle(Handle<Font>);
impl FromWorld for FontHandle {
fn from_world(world: &mut World) -> Self {
let asset_server = world.resource::<AssetServer>();
Self(asset_server.load("fonts/FiraSans-Bold.ttf"))
}
}
#[derive(Bundle)] #[derive(Bundle)]
struct GamepadButtonBundle { struct GamepadButtonBundle {
@ -126,7 +118,6 @@ fn main() {
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.init_resource::<ButtonMaterials>() .init_resource::<ButtonMaterials>()
.init_resource::<ButtonMeshes>() .init_resource::<ButtonMeshes>()
.init_resource::<FontHandle>()
.add_systems( .add_systems(
Startup, Startup,
(setup, setup_sticks, setup_triggers, setup_connected), (setup, setup_sticks, setup_triggers, setup_connected),
@ -273,7 +264,6 @@ fn setup_sticks(
meshes: Res<ButtonMeshes>, meshes: Res<ButtonMeshes>,
materials: Res<ButtonMaterials>, materials: Res<ButtonMaterials>,
gamepad_settings: Res<GamepadSettings>, gamepad_settings: Res<GamepadSettings>,
font: Res<FontHandle>,
) { ) {
let dead_upper = let dead_upper =
STICK_BOUNDS_SIZE * gamepad_settings.default_axis_settings.deadzone_upperbound(); STICK_BOUNDS_SIZE * gamepad_settings.default_axis_settings.deadzone_upperbound();
@ -329,7 +319,7 @@ fn setup_sticks(
let style = TextStyle { let style = TextStyle {
font_size: 16., font_size: 16.,
color: TEXT_COLOR, color: TEXT_COLOR,
font: font.clone(), ..default()
}; };
parent.spawn(( parent.spawn((
Text2dBundle { Text2dBundle {
@ -392,7 +382,6 @@ fn setup_triggers(
mut commands: Commands, mut commands: Commands,
meshes: Res<ButtonMeshes>, meshes: Res<ButtonMeshes>,
materials: Res<ButtonMaterials>, materials: Res<ButtonMaterials>,
font: Res<FontHandle>,
) { ) {
let mut spawn_trigger = |x, y, button_type| { let mut spawn_trigger = |x, y, button_type| {
commands commands
@ -410,9 +399,9 @@ fn setup_triggers(
text: Text::from_section( text: Text::from_section(
format!("{:.3}", 0.), format!("{:.3}", 0.),
TextStyle { TextStyle {
font: font.clone(),
font_size: 16., font_size: 16.,
color: TEXT_COLOR, color: TEXT_COLOR,
..default()
}, },
), ),
..default() ..default()
@ -434,11 +423,11 @@ fn setup_triggers(
); );
} }
fn setup_connected(mut commands: Commands, font: Res<FontHandle>) { fn setup_connected(mut commands: Commands) {
let style = TextStyle { let style = TextStyle {
color: TEXT_COLOR, color: TEXT_COLOR,
font_size: 30., font_size: 30.,
font: font.clone(), ..default()
}; };
commands.spawn(( commands.spawn((
TextBundle::from_sections([ TextBundle::from_sections([

View file

@ -148,7 +148,6 @@ pub(crate) mod test_setup {
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut event: EventWriter<RequestRedraw>, mut event: EventWriter<RequestRedraw>,
asset_server: Res<AssetServer>,
) { ) {
commands.spawn(( commands.spawn((
PbrBundle { PbrBundle {
@ -177,28 +176,28 @@ pub(crate) mod test_setup {
TextSection::new( TextSection::new(
"Press spacebar to cycle modes\n", "Press spacebar to cycle modes\n",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
), ),
TextSection::from_style(TextStyle { TextSection::from_style(TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::GREEN, color: Color::GREEN,
..default()
}), }),
TextSection::new( TextSection::new(
"\nFrame: ", "\nFrame: ",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::YELLOW, color: Color::YELLOW,
..default()
}, },
), ),
TextSection::from_style(TextStyle { TextSection::from_style(TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::YELLOW, color: Color::YELLOW,
..default()
}), }),
]) ])
.with_style(Style { .with_style(Style {

View file

@ -20,7 +20,7 @@ fn main() {
.run(); .run();
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands) {
// camera // camera
commands.spawn(Camera2dBundle::default()); commands.spawn(Camera2dBundle::default());
// root node // root node
@ -50,9 +50,9 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
TextBundle::from_section( TextBundle::from_section(
"Example text", "Example text",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
font_size: 30.0, font_size: 30.0,
color: Color::WHITE, color: Color::WHITE,
..default()
}, },
) )
.with_style(Style { .with_style(Style {

View file

@ -32,7 +32,7 @@ fn setup_camera(mut cmd: Commands) {
} }
// Spawns the UI // Spawns the UI
fn setup_ui(mut cmd: Commands, asset_server: Res<AssetServer>) { fn setup_ui(mut cmd: Commands) {
// Node that fills entire background // Node that fills entire background
cmd.spawn(NodeBundle { cmd.spawn(NodeBundle {
style: Style { style: Style {
@ -47,9 +47,9 @@ fn setup_ui(mut cmd: Commands, asset_server: Res<AssetServer>) {
TextBundle::from_section( TextBundle::from_section(
"Resolution", "Resolution",
TextStyle { TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 50.0, font_size: 50.0,
color: Color::BLACK, color: Color::BLACK,
..default()
}, },
), ),
ResolutionText, ResolutionText,