text_wrap_debug/
text_wrap_debug.rs

1//! This example demonstrates text wrapping and use of the `LineBreakOn` property.
2
3use argh::FromArgs;
4use bevy::{prelude::*, text::LineBreak, window::WindowResolution};
5
6#[derive(FromArgs, Resource)]
7/// `text_wrap_debug` demonstrates text wrapping and use of the `LineBreakOn` property
8struct Args {
9    #[argh(option)]
10    /// window scale factor
11    scale_factor: Option<f32>,
12
13    #[argh(option, default = "1.")]
14    /// ui scale factor
15    ui_scale: f32,
16}
17
18fn main() {
19    // `from_env` panics on the web
20    #[cfg(not(target_arch = "wasm32"))]
21    let args: Args = argh::from_env();
22    #[cfg(target_arch = "wasm32")]
23    let args = Args::from_args(&[], &[]).unwrap();
24
25    let window = if let Some(scale_factor) = args.scale_factor {
26        Window {
27            resolution: WindowResolution::default().with_scale_factor_override(scale_factor),
28            ..Default::default()
29        }
30    } else {
31        Window::default()
32    };
33
34    App::new()
35        .add_plugins(DefaultPlugins.set(WindowPlugin {
36            primary_window: Some(window),
37            ..Default::default()
38        }))
39        .insert_resource(UiScale(args.ui_scale))
40        .add_systems(Startup, spawn)
41        .run();
42}
43
44fn spawn(mut commands: Commands, asset_server: Res<AssetServer>) {
45    commands.spawn(Camera2d);
46
47    let text_font = TextFont {
48        font: asset_server.load("fonts/FiraSans-Bold.ttf"),
49        font_size: 12.0,
50        ..default()
51    };
52
53    let root = commands
54        .spawn((
55            Node {
56                width: percent(100),
57                height: percent(100),
58                flex_direction: FlexDirection::Column,
59                ..default()
60            },
61            BackgroundColor(Color::BLACK),
62        ))
63        .id();
64
65    for linebreak in [
66        LineBreak::AnyCharacter,
67        LineBreak::WordBoundary,
68        LineBreak::WordOrCharacter,
69        LineBreak::NoWrap,
70    ] {
71        let row_id = commands
72            .spawn(Node {
73                flex_direction: FlexDirection::Row,
74                justify_content: JustifyContent::SpaceAround,
75                align_items: AlignItems::Center,
76                width: percent(100),
77                height: percent(50),
78                ..default()
79            })
80            .id();
81
82        let justifications = vec![
83            JustifyContent::Center,
84            JustifyContent::FlexStart,
85            JustifyContent::FlexEnd,
86            JustifyContent::SpaceAround,
87            JustifyContent::SpaceBetween,
88            JustifyContent::SpaceEvenly,
89        ];
90
91        for (i, justification) in justifications.into_iter().enumerate() {
92            let c = 0.3 + i as f32 * 0.1;
93            let column_id = commands
94                .spawn((
95                    Node {
96                        justify_content: justification,
97                        flex_direction: FlexDirection::Column,
98                        width: percent(16),
99                        height: percent(95),
100                        overflow: Overflow::clip_x(),
101                        ..default()
102                    },
103                    BackgroundColor(Color::srgb(0.5, c, 1.0 - c)),
104                ))
105                .id();
106
107            let messages = [
108                format!("JustifyContent::{justification:?}"),
109                format!("LineBreakOn::{linebreak:?}"),
110                "Line 1\nLine 2".to_string(),
111                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas auctor, nunc ac faucibus fringilla.".to_string(),
112                "pneumonoultramicroscopicsilicovolcanoconiosis".to_string()
113            ];
114
115            for (j, message) in messages.into_iter().enumerate() {
116                commands.entity(column_id).with_child((
117                    Text(message.clone()),
118                    text_font.clone(),
119                    TextLayout::new(Justify::Left, linebreak),
120                    BackgroundColor(Color::srgb(0.8 - j as f32 * 0.2, 0., 0.)),
121                ));
122            }
123            commands.entity(row_id).add_child(column_id);
124        }
125        commands.entity(root).add_child(row_id);
126    }
127}