ui: feed computed text position into bevy_ui flex
and remove TextAlign because it is now redundant
This commit is contained in:
		
							parent
							
								
									1f006c348d
								
							
						
					
					
						commit
						cf9501a50e
					
				@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign};
 | 
				
			|||||||
use glam::Vec2;
 | 
					use glam::Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq, Debug)]
 | 
					#[derive(Copy, Clone, PartialEq, Debug)]
 | 
				
			||||||
pub struct Size<T> {
 | 
					pub struct Size<T=f32> {
 | 
				
			||||||
    pub width: T,
 | 
					    pub width: T,
 | 
				
			||||||
    pub height: T,
 | 
					    pub height: T,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
use crate::{Font, FontAtlasSet};
 | 
					use crate::{Font, FontAtlasSet};
 | 
				
			||||||
use ab_glyph::{FontVec, Glyph, PxScale, PxScaleFont, ScaleFont};
 | 
					use ab_glyph::{Glyph, PxScale, ScaleFont};
 | 
				
			||||||
use bevy_asset::Assets;
 | 
					use bevy_asset::Assets;
 | 
				
			||||||
use bevy_math::{Mat4, Vec2, Vec3};
 | 
					use bevy_math::{Mat4, Vec2, Vec3};
 | 
				
			||||||
use bevy_render::{
 | 
					use bevy_render::{
 | 
				
			||||||
@ -17,7 +17,6 @@ use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
 | 
				
			|||||||
pub struct TextStyle {
 | 
					pub struct TextStyle {
 | 
				
			||||||
    pub font_size: f32,
 | 
					    pub font_size: f32,
 | 
				
			||||||
    pub color: Color,
 | 
					    pub color: Color,
 | 
				
			||||||
    pub align: TextAlign,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for TextStyle {
 | 
					impl Default for TextStyle {
 | 
				
			||||||
@ -25,23 +24,10 @@ impl Default for TextStyle {
 | 
				
			|||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            color: Color::WHITE,
 | 
					            color: Color::WHITE,
 | 
				
			||||||
            font_size: 12.0,
 | 
					            font_size: 12.0,
 | 
				
			||||||
            align: TextAlign::default(),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum TextAlign {
 | 
					 | 
				
			||||||
    Left,
 | 
					 | 
				
			||||||
    Center,
 | 
					 | 
				
			||||||
    Right,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for TextAlign {
 | 
					 | 
				
			||||||
    fn default() -> Self {
 | 
					 | 
				
			||||||
        TextAlign::Left
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct DrawableText<'a> {
 | 
					pub struct DrawableText<'a> {
 | 
				
			||||||
    pub font: &'a Font,
 | 
					    pub font: &'a Font,
 | 
				
			||||||
    pub font_atlas_set: &'a FontAtlasSet,
 | 
					    pub font_atlas_set: &'a FontAtlasSet,
 | 
				
			||||||
@ -54,26 +40,6 @@ pub struct DrawableText<'a> {
 | 
				
			|||||||
    pub text: &'a str,
 | 
					    pub text: &'a str,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn get_text_width(text: &str, scaled_font: &PxScaleFont<&&FontVec>) -> f32 {
 | 
					 | 
				
			||||||
    let mut last_glyph: Option<Glyph> = None;
 | 
					 | 
				
			||||||
    let mut position = 0.0;
 | 
					 | 
				
			||||||
    for character in text.chars() {
 | 
					 | 
				
			||||||
        if character.is_control() {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let glyph = scaled_font.scaled_glyph(character);
 | 
					 | 
				
			||||||
        if let Some(last_glyph) = last_glyph.take() {
 | 
					 | 
				
			||||||
            position += scaled_font.kern(last_glyph.id, glyph.id);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        position += scaled_font.h_advance(glyph.id);
 | 
					 | 
				
			||||||
        last_glyph = Some(glyph);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    position
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl<'a> Drawable for DrawableText<'a> {
 | 
					impl<'a> Drawable for DrawableText<'a> {
 | 
				
			||||||
    fn draw(&mut self, draw: &mut Draw, context: &mut DrawContext) -> Result<(), DrawError> {
 | 
					    fn draw(&mut self, draw: &mut Draw, context: &mut DrawContext) -> Result<(), DrawError> {
 | 
				
			||||||
        context.set_pipeline(
 | 
					        context.set_pipeline(
 | 
				
			||||||
@ -109,17 +75,6 @@ impl<'a> Drawable for DrawableText<'a> {
 | 
				
			|||||||
        let scale = PxScale::from(self.style.font_size);
 | 
					        let scale = PxScale::from(self.style.font_size);
 | 
				
			||||||
        let scaled_font = ab_glyph::Font::as_scaled(&font, scale);
 | 
					        let scaled_font = ab_glyph::Font::as_scaled(&font, scale);
 | 
				
			||||||
        let mut caret = self.position;
 | 
					        let mut caret = self.position;
 | 
				
			||||||
        match self.style.align {
 | 
					 | 
				
			||||||
            TextAlign::Left => { /* already aligned left by default */ }
 | 
					 | 
				
			||||||
            TextAlign::Center => {
 | 
					 | 
				
			||||||
                *caret.x_mut() +=
 | 
					 | 
				
			||||||
                    self.container_size.x() / 2.0 - get_text_width(&self.text, &scaled_font) / 2.0
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            TextAlign::Right => {
 | 
					 | 
				
			||||||
                *caret.x_mut() += self.container_size.x() - get_text_width(&self.text, &scaled_font)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut last_glyph: Option<Glyph> = None;
 | 
					        let mut last_glyph: Option<Glyph> = None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // set local per-character bindings
 | 
					        // set local per-character bindings
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
use crate::{Font, FontAtlas};
 | 
					use crate::{Font, FontAtlas};
 | 
				
			||||||
use ab_glyph::ScaleFont;
 | 
					use ab_glyph::{Glyph, ScaleFont};
 | 
				
			||||||
use bevy_asset::{Assets, Handle};
 | 
					use bevy_asset::{Assets, Handle};
 | 
				
			||||||
use bevy_core::FloatOrd;
 | 
					use bevy_core::FloatOrd;
 | 
				
			||||||
use bevy_math::Vec2;
 | 
					use bevy_math::Vec2;
 | 
				
			||||||
@ -49,24 +49,35 @@ impl FontAtlasSet {
 | 
				
			|||||||
        textures: &mut Assets<Texture>,
 | 
					        textures: &mut Assets<Texture>,
 | 
				
			||||||
        font_size: f32,
 | 
					        font_size: f32,
 | 
				
			||||||
        text: &str,
 | 
					        text: &str,
 | 
				
			||||||
    ) {
 | 
					    ) -> f32 {
 | 
				
			||||||
        let font = fonts.get(&self.font).unwrap();
 | 
					        let font = fonts.get(&self.font).unwrap();
 | 
				
			||||||
        let scaled_font = ab_glyph::Font::as_scaled(&font.font, font_size);
 | 
					        let scaled_font = ab_glyph::Font::as_scaled(&font.font, font_size);
 | 
				
			||||||
        let font_atlas = self
 | 
					        let font_atlas = self
 | 
				
			||||||
            .font_atlases
 | 
					            .font_atlases
 | 
				
			||||||
            .entry(FloatOrd(font_size))
 | 
					            .entry(FloatOrd(font_size))
 | 
				
			||||||
            .or_insert_with(|| FontAtlas::new(textures, texture_atlases, Vec2::new(512.0, 512.0)));
 | 
					            .or_insert_with(|| FontAtlas::new(textures, texture_atlases, Vec2::new(512.0, 512.0)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut last_glyph: Option<Glyph> = None;
 | 
				
			||||||
 | 
					        let mut width = 0.0;
 | 
				
			||||||
        for character in text.chars() {
 | 
					        for character in text.chars() {
 | 
				
			||||||
            if character.is_control() || font_atlas.get_char_index(character).is_some() {
 | 
					            if character.is_control() {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            let glyph = scaled_font.scaled_glyph(character);
 | 
					            let glyph = scaled_font.scaled_glyph(character);
 | 
				
			||||||
            if let Some(outlined_glyph) = scaled_font.outline_glyph(glyph) {
 | 
					            if let Some(last_glyph) = last_glyph.take() {
 | 
				
			||||||
                let glyph_texture = Font::get_outlined_glyph_texture(outlined_glyph);
 | 
					                width += scaled_font.kern(last_glyph.id, glyph.id);
 | 
				
			||||||
                font_atlas.add_char(textures, texture_atlases, character, &glyph_texture);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if font_atlas.get_char_index(character).is_none() {
 | 
				
			||||||
 | 
					                if let Some(outlined_glyph) = scaled_font.outline_glyph(glyph.clone()) {
 | 
				
			||||||
 | 
					                    let glyph_texture = Font::get_outlined_glyph_texture(outlined_glyph);
 | 
				
			||||||
 | 
					                    font_atlas.add_char(textures, texture_atlases, character, &glyph_texture);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            width += scaled_font.h_advance(glyph.id);
 | 
				
			||||||
 | 
					            last_glyph = Some(glyph);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        width
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_glyph_atlas_info(&self, font_size: f32, character: char) -> Option<GlyphAtlasInfo> {
 | 
					    pub fn get_glyph_atlas_info(&self, font_size: f32, character: char) -> Option<GlyphAtlasInfo> {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ pub use font_atlas_set::*;
 | 
				
			|||||||
pub use font_loader::*;
 | 
					pub use font_loader::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod prelude {
 | 
					pub mod prelude {
 | 
				
			||||||
    pub use crate::{Font, TextAlign, TextStyle};
 | 
					    pub use crate::{Font, TextStyle};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use bevy_app::prelude::*;
 | 
					use bevy_app::prelude::*;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ use super::Node;
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    render::UI_PIPELINE_HANDLE,
 | 
					    render::UI_PIPELINE_HANDLE,
 | 
				
			||||||
    widget::{Button, Text},
 | 
					    widget::{Button, Text},
 | 
				
			||||||
    Click, FocusPolicy, Hover, Style,
 | 
					    Click, FocusPolicy, Hover, Style, CalculatedSize,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_asset::Handle;
 | 
					use bevy_asset::Handle;
 | 
				
			||||||
use bevy_ecs::Bundle;
 | 
					use bevy_ecs::Bundle;
 | 
				
			||||||
@ -68,6 +68,7 @@ pub struct TextComponents {
 | 
				
			|||||||
    pub style: Style,
 | 
					    pub style: Style,
 | 
				
			||||||
    pub draw: Draw,
 | 
					    pub draw: Draw,
 | 
				
			||||||
    pub text: Text,
 | 
					    pub text: Text,
 | 
				
			||||||
 | 
					    pub calculated_size: CalculatedSize,
 | 
				
			||||||
    pub focus_policy: FocusPolicy,
 | 
					    pub focus_policy: FocusPolicy,
 | 
				
			||||||
    pub transform: Transform,
 | 
					    pub transform: Transform,
 | 
				
			||||||
    pub local_transform: LocalTransform,
 | 
					    pub local_transform: LocalTransform,
 | 
				
			||||||
@ -83,6 +84,7 @@ impl Default for TextComponents {
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
            text: Default::default(),
 | 
					            text: Default::default(),
 | 
				
			||||||
            node: Default::default(),
 | 
					            node: Default::default(),
 | 
				
			||||||
 | 
					            calculated_size: Default::default(),
 | 
				
			||||||
            style: Default::default(),
 | 
					            style: Default::default(),
 | 
				
			||||||
            transform: Default::default(),
 | 
					            transform: Default::default(),
 | 
				
			||||||
            local_transform: Default::default(),
 | 
					            local_transform: Default::default(),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
mod convert;
 | 
					mod convert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{Style, Node};
 | 
					use crate::{CalculatedSize, Node, Style};
 | 
				
			||||||
use bevy_ecs::{Changed, Entity, Query, Res, ResMut, With, Without};
 | 
					use bevy_ecs::{Changed, Entity, Query, Res, ResMut, With, Without};
 | 
				
			||||||
use bevy_math::Vec2;
 | 
					use bevy_math::Vec2;
 | 
				
			||||||
use bevy_transform::prelude::{Children, LocalTransform, Parent};
 | 
					use bevy_transform::prelude::{Children, LocalTransform, Parent};
 | 
				
			||||||
@ -10,7 +10,6 @@ use stretch::Stretch;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct FlexSurface {
 | 
					pub struct FlexSurface {
 | 
				
			||||||
    entity_to_stretch: HashMap<Entity, stretch::node::Node>,
 | 
					    entity_to_stretch: HashMap<Entity, stretch::node::Node>,
 | 
				
			||||||
    stretch_to_entity: HashMap<stretch::node::Node, Entity>,
 | 
					 | 
				
			||||||
    window_nodes: HashMap<WindowId, stretch::node::Node>,
 | 
					    window_nodes: HashMap<WindowId, stretch::node::Node>,
 | 
				
			||||||
    stretch: Stretch,
 | 
					    stretch: Stretch,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -19,7 +18,6 @@ impl Default for FlexSurface {
 | 
				
			|||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            entity_to_stretch: Default::default(),
 | 
					            entity_to_stretch: Default::default(),
 | 
				
			||||||
            stretch_to_entity: Default::default(),
 | 
					 | 
				
			||||||
            window_nodes: Default::default(),
 | 
					            window_nodes: Default::default(),
 | 
				
			||||||
            stretch: Stretch::new(),
 | 
					            stretch: Stretch::new(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -30,12 +28,10 @@ impl FlexSurface {
 | 
				
			|||||||
    pub fn upsert_node(&mut self, entity: Entity, style: &Style) {
 | 
					    pub fn upsert_node(&mut self, entity: Entity, style: &Style) {
 | 
				
			||||||
        let mut added = false;
 | 
					        let mut added = false;
 | 
				
			||||||
        let stretch = &mut self.stretch;
 | 
					        let stretch = &mut self.stretch;
 | 
				
			||||||
        let stretch_to_entity = &mut self.stretch_to_entity;
 | 
					 | 
				
			||||||
        let stretch_style = style.into();
 | 
					        let stretch_style = style.into();
 | 
				
			||||||
        let stretch_node = self.entity_to_stretch.entry(entity).or_insert_with(|| {
 | 
					        let stretch_node = self.entity_to_stretch.entry(entity).or_insert_with(|| {
 | 
				
			||||||
            added = true;
 | 
					            added = true;
 | 
				
			||||||
            let stretch_node = stretch.new_node(stretch_style, Vec::new()).unwrap();
 | 
					            let stretch_node = stretch.new_node(stretch_style, Vec::new()).unwrap();
 | 
				
			||||||
            stretch_to_entity.insert(stretch_node, entity);
 | 
					 | 
				
			||||||
            stretch_node
 | 
					            stretch_node
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,6 +42,44 @@ impl FlexSurface {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn upsert_leaf(&mut self, entity: Entity, style: &Style, calculated_size: CalculatedSize) {
 | 
				
			||||||
 | 
					        let mut added = false;
 | 
				
			||||||
 | 
					        let stretch = &mut self.stretch;
 | 
				
			||||||
 | 
					        let stretch_style = style.into();
 | 
				
			||||||
 | 
					        let stretch_node = self.entity_to_stretch.entry(entity).or_insert_with(|| {
 | 
				
			||||||
 | 
					            added = true;
 | 
				
			||||||
 | 
					            let stretch_node = stretch
 | 
				
			||||||
 | 
					                .new_leaf(
 | 
				
			||||||
 | 
					                    stretch_style,
 | 
				
			||||||
 | 
					                    Box::new(move |_| {
 | 
				
			||||||
 | 
					                        Ok(stretch::geometry::Size {
 | 
				
			||||||
 | 
					                            width: calculated_size.size.width,
 | 
				
			||||||
 | 
					                            height: calculated_size.size.height,
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					            stretch_node
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if !added {
 | 
				
			||||||
 | 
					            self.stretch
 | 
				
			||||||
 | 
					                .set_style(*stretch_node, stretch_style)
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					            self.stretch
 | 
				
			||||||
 | 
					                .set_measure(
 | 
				
			||||||
 | 
					                    *stretch_node,
 | 
				
			||||||
 | 
					                    Some(Box::new(move |_| {
 | 
				
			||||||
 | 
					                        Ok(stretch::geometry::Size {
 | 
				
			||||||
 | 
					                            width: calculated_size.size.width,
 | 
				
			||||||
 | 
					                            height: calculated_size.size.height,
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                    })),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn update_children(&mut self, entity: Entity, children: &Children) {
 | 
					    pub fn update_children(&mut self, entity: Entity, children: &Children) {
 | 
				
			||||||
        let mut stretch_children = Vec::with_capacity(children.len());
 | 
					        let mut stretch_children = Vec::with_capacity(children.len());
 | 
				
			||||||
        for child in children.iter() {
 | 
					        for child in children.iter() {
 | 
				
			||||||
@ -63,10 +97,7 @@ impl FlexSurface {
 | 
				
			|||||||
        let stretch = &mut self.stretch;
 | 
					        let stretch = &mut self.stretch;
 | 
				
			||||||
        let node = self.window_nodes.entry(window.id).or_insert_with(|| {
 | 
					        let node = self.window_nodes.entry(window.id).or_insert_with(|| {
 | 
				
			||||||
            stretch
 | 
					            stretch
 | 
				
			||||||
                .new_node(
 | 
					                .new_node(stretch::style::Style::default(), Vec::new())
 | 
				
			||||||
                    stretch::style::Style::default(),
 | 
					 | 
				
			||||||
                    Vec::new(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .unwrap()
 | 
					                .unwrap()
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -120,7 +151,8 @@ pub fn flex_node_system(
 | 
				
			|||||||
    windows: Res<Windows>,
 | 
					    windows: Res<Windows>,
 | 
				
			||||||
    mut flex_surface: ResMut<FlexSurface>,
 | 
					    mut flex_surface: ResMut<FlexSurface>,
 | 
				
			||||||
    mut root_node_query: Query<With<Node, Without<Parent, Entity>>>,
 | 
					    mut root_node_query: Query<With<Node, Without<Parent, Entity>>>,
 | 
				
			||||||
    mut node_query: Query<With<Node, (Entity, Changed<Style>)>>,
 | 
					    mut node_query: Query<With<Node, (Entity, Changed<Style>, Option<&CalculatedSize>)>>,
 | 
				
			||||||
 | 
					    mut changed_size_query: Query<With<Node, (Entity, &Style, Changed<CalculatedSize>)>>,
 | 
				
			||||||
    mut children_query: Query<With<Node, (Entity, Changed<Children>)>>,
 | 
					    mut children_query: Query<With<Node, (Entity, Changed<Children>)>>,
 | 
				
			||||||
    mut node_transform_query: Query<(Entity, &mut Node, &mut LocalTransform, Option<&Parent>)>,
 | 
					    mut node_transform_query: Query<(Entity, &mut Node, &mut LocalTransform, Option<&Parent>)>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
@ -130,9 +162,17 @@ pub fn flex_node_system(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // update changed nodes
 | 
					    // update changed nodes
 | 
				
			||||||
    for (entity, style) in &mut node_query.iter() {
 | 
					    for (entity, style, calculated_size) in &mut node_query.iter() {
 | 
				
			||||||
        // TODO: remove node from old hierarchy if its root has changed
 | 
					        // TODO: remove node from old hierarchy if its root has changed
 | 
				
			||||||
        flex_surface.upsert_node(entity, &style);
 | 
					        if let Some(calculated_size) = calculated_size {
 | 
				
			||||||
 | 
					            flex_surface.upsert_leaf(entity, &style, *calculated_size);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            flex_surface.upsert_node(entity, &style);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (entity, style, calculated_size) in &mut changed_size_query.iter() {
 | 
				
			||||||
 | 
					        flex_surface.upsert_leaf(entity, &style, *calculated_size);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: handle removed nodes
 | 
					    // TODO: handle removed nodes
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ impl AppPlugin for UiPlugin {
 | 
				
			|||||||
            // add these stages to front because these must run before transform update systems
 | 
					            // add these stages to front because these must run before transform update systems
 | 
				
			||||||
            .add_system_to_stage_front(stage::POST_UPDATE, flex_node_system.system())
 | 
					            .add_system_to_stage_front(stage::POST_UPDATE, flex_node_system.system())
 | 
				
			||||||
            .add_system_to_stage_front(stage::POST_UPDATE, ui_z_system.system())
 | 
					            .add_system_to_stage_front(stage::POST_UPDATE, ui_z_system.system())
 | 
				
			||||||
            .add_system_to_stage(stage::POST_UPDATE, widget::text_system.system())
 | 
					            .add_system_to_stage_front(stage::POST_UPDATE, widget::text_system.system())
 | 
				
			||||||
            .add_system_to_stage(bevy_render::stage::DRAW, widget::draw_text_system.system());
 | 
					            .add_system_to_stage(bevy_render::stage::DRAW, widget::draw_text_system.system());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let resources = app.resources();
 | 
					        let resources = app.resources();
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,11 @@ impl AddAssign<f32> for Val {
 | 
				
			|||||||
            Val::Percent(value) => *value += rhs,
 | 
					            Val::Percent(value) => *value += rhs,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Default, Copy, Clone)]
 | 
				
			||||||
 | 
					pub struct CalculatedSize {
 | 
				
			||||||
 | 
					    pub size: Size,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, PartialEq, Debug)]
 | 
					#[derive(Clone, PartialEq, Debug)]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
use crate::Node;
 | 
					use crate::{CalculatedSize, Node};
 | 
				
			||||||
use bevy_asset::{Assets, Handle};
 | 
					use bevy_asset::{Assets, Handle};
 | 
				
			||||||
use bevy_ecs::{Query, Res, ResMut};
 | 
					use bevy_ecs::{Changed, Query, Res, ResMut};
 | 
				
			||||||
 | 
					use bevy_math::Size;
 | 
				
			||||||
use bevy_render::{
 | 
					use bevy_render::{
 | 
				
			||||||
    draw::{Draw, DrawContext, Drawable},
 | 
					    draw::{Draw, DrawContext, Drawable},
 | 
				
			||||||
    renderer::{AssetRenderResourceBindings, RenderResourceBindings},
 | 
					    renderer::{AssetRenderResourceBindings, RenderResourceBindings},
 | 
				
			||||||
@ -22,9 +23,9 @@ pub fn text_system(
 | 
				
			|||||||
    fonts: Res<Assets<Font>>,
 | 
					    fonts: Res<Assets<Font>>,
 | 
				
			||||||
    mut font_atlas_sets: ResMut<Assets<FontAtlasSet>>,
 | 
					    mut font_atlas_sets: ResMut<Assets<FontAtlasSet>>,
 | 
				
			||||||
    mut texture_atlases: ResMut<Assets<TextureAtlas>>,
 | 
					    mut texture_atlases: ResMut<Assets<TextureAtlas>>,
 | 
				
			||||||
    mut query: Query<&Text>,
 | 
					    mut query: Query<(Changed<Text>, &mut CalculatedSize)>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    for text in &mut query.iter() {
 | 
					    for (text, mut calculated_size) in &mut query.iter() {
 | 
				
			||||||
        let font_atlases = font_atlas_sets
 | 
					        let font_atlases = font_atlas_sets
 | 
				
			||||||
            .get_or_insert_with(Handle::from_id(text.font.id), || {
 | 
					            .get_or_insert_with(Handle::from_id(text.font.id), || {
 | 
				
			||||||
                FontAtlasSet::new(text.font)
 | 
					                FontAtlasSet::new(text.font)
 | 
				
			||||||
@ -35,13 +36,15 @@ pub fn text_system(
 | 
				
			|||||||
        // resource generation needs to happen AFTER the render graph systems. maybe draw systems should execute within the
 | 
					        // resource generation needs to happen AFTER the render graph systems. maybe draw systems should execute within the
 | 
				
			||||||
        // render graph so ordering like this can be taken into account? Maybe the RENDER_GRAPH_SYSTEMS stage should be removed entirely
 | 
					        // render graph so ordering like this can be taken into account? Maybe the RENDER_GRAPH_SYSTEMS stage should be removed entirely
 | 
				
			||||||
        // in favor of node.update()? Regardless, in the immediate short term the current approach is fine.
 | 
					        // in favor of node.update()? Regardless, in the immediate short term the current approach is fine.
 | 
				
			||||||
        font_atlases.add_glyphs_to_atlas(
 | 
					        let width = font_atlases.add_glyphs_to_atlas(
 | 
				
			||||||
            &fonts,
 | 
					            &fonts,
 | 
				
			||||||
            &mut texture_atlases,
 | 
					            &mut texture_atlases,
 | 
				
			||||||
            &mut textures,
 | 
					            &mut textures,
 | 
				
			||||||
            text.style.font_size,
 | 
					            text.style.font_size,
 | 
				
			||||||
            &text.value,
 | 
					            &text.value,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        calculated_size.size = Size::new(width, text.style.font_size);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -71,7 +71,6 @@ fn setup(
 | 
				
			|||||||
                style: TextStyle {
 | 
					                style: TextStyle {
 | 
				
			||||||
                    color: Color::rgb(0.2, 0.2, 0.8).into(),
 | 
					                    color: Color::rgb(0.2, 0.2, 0.8).into(),
 | 
				
			||||||
                    font_size: 40.0,
 | 
					                    font_size: 40.0,
 | 
				
			||||||
                    ..Default::default()
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            style: Style {
 | 
					            style: Style {
 | 
				
			||||||
 | 
				
			|||||||
@ -95,13 +95,13 @@ fn setup(
 | 
				
			|||||||
        .spawn(UiCameraComponents::default())
 | 
					        .spawn(UiCameraComponents::default())
 | 
				
			||||||
        .spawn(ButtonComponents {
 | 
					        .spawn(ButtonComponents {
 | 
				
			||||||
            style: Style {
 | 
					            style: Style {
 | 
				
			||||||
                size: Size::new(Val::Px(150.0), Val::Px(70.0)),
 | 
					                size: Size::new(Val::Px(150.0), Val::Px(65.0)),
 | 
				
			||||||
                align_self: AlignSelf::Center,
 | 
					                // center button
 | 
				
			||||||
                margin: Rect {
 | 
					                margin: Rect::all(Val::Auto),
 | 
				
			||||||
                    left: Val::Auto,
 | 
					                // horizontally center child text
 | 
				
			||||||
                    right: Val::Auto,
 | 
					                justify_content: JustifyContent::Center,
 | 
				
			||||||
                    ..Default::default()
 | 
					                // vertically center child text
 | 
				
			||||||
                },
 | 
					                align_items: AlignItems::Center,
 | 
				
			||||||
                ..Default::default()
 | 
					                ..Default::default()
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            material: button_materials.normal,
 | 
					            material: button_materials.normal,
 | 
				
			||||||
@ -109,21 +109,12 @@ fn setup(
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
        .with_children(|parent| {
 | 
					        .with_children(|parent| {
 | 
				
			||||||
            parent.spawn(TextComponents {
 | 
					            parent.spawn(TextComponents {
 | 
				
			||||||
                style: Style {
 | 
					 | 
				
			||||||
                    size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
 | 
					 | 
				
			||||||
                    margin: Rect {
 | 
					 | 
				
			||||||
                        bottom: Val::Px(10.0),
 | 
					 | 
				
			||||||
                        ..Default::default()
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    ..Default::default()
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                text: Text {
 | 
					                text: Text {
 | 
				
			||||||
                    value: "Button".to_string(),
 | 
					                    value: "Button".to_string(),
 | 
				
			||||||
                    font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(),
 | 
					                    font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(),
 | 
				
			||||||
                    style: TextStyle {
 | 
					                    style: TextStyle {
 | 
				
			||||||
                        font_size: 40.0,
 | 
					                        font_size: 40.0,
 | 
				
			||||||
                        color: Color::rgb(0.8, 0.8, 0.8),
 | 
					                        color: Color::rgb(0.8, 0.8, 0.8),
 | 
				
			||||||
                        align: TextAlign::Center,
 | 
					 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                ..Default::default()
 | 
					                ..Default::default()
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResM
 | 
				
			|||||||
                style: TextStyle {
 | 
					                style: TextStyle {
 | 
				
			||||||
                    font_size: 60.0,
 | 
					                    font_size: 60.0,
 | 
				
			||||||
                    color: Color::WHITE,
 | 
					                    color: Color::WHITE,
 | 
				
			||||||
                    ..Default::default()
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            ..Default::default()
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
				
			|||||||
@ -26,17 +26,19 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
 | 
				
			|||||||
    let font_handle = asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap();
 | 
					    let font_handle = asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap();
 | 
				
			||||||
    commands
 | 
					    commands
 | 
				
			||||||
        // 2d camera
 | 
					        // 2d camera
 | 
				
			||||||
        .spawn(Camera2dComponents::default())
 | 
					        .spawn(UiCameraComponents::default())
 | 
				
			||||||
        // texture
 | 
					        // texture
 | 
				
			||||||
        .spawn(TextComponents {
 | 
					        .spawn(TextComponents {
 | 
				
			||||||
            node: Node::default(),
 | 
					            style: Style {
 | 
				
			||||||
 | 
					                align_self: AlignSelf::FlexEnd,
 | 
				
			||||||
 | 
					                ..Default::default()
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            text: Text {
 | 
					            text: Text {
 | 
				
			||||||
                value: "FPS:".to_string(),
 | 
					                value: "FPS:".to_string(),
 | 
				
			||||||
                font: font_handle,
 | 
					                font: font_handle,
 | 
				
			||||||
                style: TextStyle {
 | 
					                style: TextStyle {
 | 
				
			||||||
                    font_size: 60.0,
 | 
					                    font_size: 60.0,
 | 
				
			||||||
                    color: Color::WHITE,
 | 
					                    color: Color::WHITE,
 | 
				
			||||||
                    align: TextAlign::Left,
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            ..Default::default()
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
				
			|||||||
@ -61,12 +61,7 @@ fn setup(
 | 
				
			|||||||
                            // text
 | 
					                            // text
 | 
				
			||||||
                            parent.spawn(TextComponents {
 | 
					                            parent.spawn(TextComponents {
 | 
				
			||||||
                                style: Style {
 | 
					                                style: Style {
 | 
				
			||||||
                                    size: Size::new(Val::Px(100.0), Val::Px(30.0)),
 | 
					                                    margin: Rect::all(Val::Px(5.0)),
 | 
				
			||||||
                                    margin: Rect {
 | 
					 | 
				
			||||||
                                        left: Val::Px(5.0),
 | 
					 | 
				
			||||||
                                        top: Val::Px(5.0),
 | 
					 | 
				
			||||||
                                        ..Default::default()
 | 
					 | 
				
			||||||
                                    },
 | 
					 | 
				
			||||||
                                    ..Default::default()
 | 
					                                    ..Default::default()
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                text: Text {
 | 
					                                text: Text {
 | 
				
			||||||
@ -77,7 +72,6 @@ fn setup(
 | 
				
			|||||||
                                    style: TextStyle {
 | 
					                                    style: TextStyle {
 | 
				
			||||||
                                        font_size: 30.0,
 | 
					                                        font_size: 30.0,
 | 
				
			||||||
                                        color: Color::WHITE,
 | 
					                                        color: Color::WHITE,
 | 
				
			||||||
                                        ..Default::default()
 | 
					 | 
				
			||||||
                                    },
 | 
					                                    },
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                ..Default::default()
 | 
					                                ..Default::default()
 | 
				
			||||||
@ -103,7 +97,7 @@ fn setup(
 | 
				
			|||||||
                            bottom: Val::Px(10.0),
 | 
					                            bottom: Val::Px(10.0),
 | 
				
			||||||
                            ..Default::default()
 | 
					                            ..Default::default()
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        border: Rect::all(Val::Px(10.0)),
 | 
					                        border: Rect::all(Val::Px(20.0)),
 | 
				
			||||||
                        ..Default::default()
 | 
					                        ..Default::default()
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    material: materials.add(Color::rgb(0.1, 0.1, 1.0).into()),
 | 
					                    material: materials.add(Color::rgb(0.1, 0.1, 1.0).into()),
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user