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