From 1f006c348d17990872fc7c7634eb0ad5a6697454 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 27 Jul 2020 19:12:48 -0700 Subject: [PATCH] ui: fix examples, flip fix stretch axis incompatibility, ergonomics --- crates/bevy_math/src/geometry.rs | 19 +- crates/bevy_ui/src/flex/convert.rs | 11 +- crates/bevy_winit/src/lib.rs | 1 - examples/ui/button.rs | 68 +++--- examples/ui/ui.rs | 329 ++++++++++++++--------------- examples/ui/ui_bench.rs | 6 +- 6 files changed, 209 insertions(+), 225 deletions(-) diff --git a/crates/bevy_math/src/geometry.rs b/crates/bevy_math/src/geometry.rs index 7baffc9be2..5688ca86ae 100644 --- a/crates/bevy_math/src/geometry.rs +++ b/crates/bevy_math/src/geometry.rs @@ -24,17 +24,28 @@ impl Default for Size { #[derive(Copy, Clone, PartialEq, Debug)] pub struct Rect { - pub start: T, - pub end: T, + pub left: T, + pub right: T, pub top: T, pub bottom: T, } +impl Rect { + pub fn all(value: T) -> Self where T: Clone{ + Rect { + left: value.clone(), + right: value.clone(), + top: value.clone(), + bottom: value, + } + } +} + impl Default for Rect { fn default() -> Self { Self { - start: Default::default(), - end: Default::default(), + left: Default::default(), + right: Default::default(), top: Default::default(), bottom: Default::default(), } diff --git a/crates/bevy_ui/src/flex/convert.rs b/crates/bevy_ui/src/flex/convert.rs index 43f10eb2fd..61698eb80f 100644 --- a/crates/bevy_ui/src/flex/convert.rs +++ b/crates/bevy_ui/src/flex/convert.rs @@ -9,10 +9,11 @@ where T: From, { stretch::geometry::Rect { - start: rect.start.into(), - end: rect.end.into(), - top: rect.top.into(), - bottom: rect.bottom.into(), + start: rect.left.into(), + end: rect.right.into(), + // NOTE: top and bottom are intentionally flipped. stretch has a flipped y-axis + top: rect.bottom.into(), + bottom: rect.top.into(), } } @@ -61,7 +62,7 @@ impl From for stretch::style::Dimension { fn from(val: Val) -> Self { match val { Val::Auto => stretch::style::Dimension::Auto, - Val::Percent(value) => stretch::style::Dimension::Percent(value), + Val::Percent(value) => stretch::style::Dimension::Percent(value / 100.0), Val::Px(value) => stretch::style::Dimension::Points(value), Val::Undefined => stretch::style::Dimension::Undefined, } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 309b1d7947..41a9d1d498 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -88,7 +88,6 @@ pub fn winit_runner(mut app: App) { .resources .get_mut::>() .unwrap(); - let windows = app.resources.get_mut::().unwrap(); let winit_windows = app.resources.get_mut::().unwrap(); let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); window_close_requested_events.send(WindowCloseRequested { id: window_id }); diff --git a/examples/ui/button.rs b/examples/ui/button.rs index 0064fee648..92e42b942f 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -87,64 +87,46 @@ fn button_system( fn setup( mut commands: Commands, - mut materials: ResMut>, asset_server: Res, button_materials: Res, ) { commands // ui camera .spawn(UiCameraComponents::default()) - // wrapper component to center with flexbox - .spawn(NodeComponents { + .spawn(ButtonComponents { style: Style { - size: Size { - width: Val::Percent(1.0), - height: Val::Percent(1.0), + size: Size::new(Val::Px(150.0), Val::Px(70.0)), + align_self: AlignSelf::Center, + margin: Rect { + left: Val::Auto, + right: Val::Auto, + ..Default::default() }, - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, ..Default::default() }, - material: materials.add(Color::NONE.into()), + material: button_materials.normal, ..Default::default() }) .with_children(|parent| { - parent - .spawn(ButtonComponents { - style: Style { - size: Size { - width: Val::Px(150.0), - height: Val::Px(70.0), - }, + 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() }, - material: button_materials.normal, ..Default::default() - }) - .with_children(|parent| { - parent.spawn(TextComponents { - style: Style { - size: Size { - width: Val::Percent(1.0), - height: Val::Percent(1.0), - }, - margin: Rect { - top: Val::Px(10.0), - ..Default::default() - }, - ..Default::default() - }, - text: Text { - value: "Button".to_string(), - font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(), - style: TextStyle { - font_size: 40.0, - color: Color::rgb(0.8, 0.8, 0.8), - align: TextAlign::Center, - }, - }, - ..Default::default() - }); - }); + }, + text: Text { + value: "Button".to_string(), + font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(), + style: TextStyle { + font_size: 40.0, + color: Color::rgb(0.8, 0.8, 0.8), + align: TextAlign::Center, + }, + }, + ..Default::default() + }); }); } diff --git a/examples/ui/ui.rs b/examples/ui/ui.rs index 3485c641d3..daf4b96a87 100644 --- a/examples/ui/ui.rs +++ b/examples/ui/ui.rs @@ -13,12 +13,12 @@ fn setup( mut textures: ResMut>, mut materials: ResMut>, ) { - // let texture_handle = asset_server - // .load_sync(&mut textures, "assets/branding/bevy_logo_dark_big.png") - // .unwrap(); + let texture_handle = asset_server + .load_sync(&mut textures, "assets/branding/bevy_logo_dark_big.png") + .unwrap(); - // let texture = textures.get(&texture_handle).unwrap(); - // let aspect = texture.aspect(); + let texture = textures.get(&texture_handle).unwrap(); + let aspect = texture.aspect(); commands // ui camera @@ -26,10 +26,7 @@ fn setup( // root node .spawn(NodeComponents { style: Style { - size: Size { - width: Val::Percent(1.0), - height: Val::Percent(1.0), - }, + size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), justify_content: JustifyContent::SpaceBetween, ..Default::default() }, @@ -38,49 +35,37 @@ fn setup( }) .with_children(|parent| { parent - // left vertical fill + // left vertical fill (border) .spawn(NodeComponents { style: Style { - size: Size { - width: Val::Px(200.0), - height: Val::Percent(1.0), - }, - border: Rect { - start: Val::Px(10.0), - end: Val::Px(10.0), - top: Val::Px(10.0), - bottom: Val::Px(10.0), - }, + size: Size::new(Val::Px(200.0), Val::Percent(100.0)), + border: Rect::all(Val::Px(2.0)), ..Default::default() }, - material: materials.add(Color::rgb(0.02, 0.02, 0.8).into()), + material: materials.add(Color::rgb(0.4, 0.4, 0.4).into()), ..Default::default() }) .with_children(|parent| { parent + // left vertical fill (content) .spawn(NodeComponents { style: Style { - size: Size { - width: Val::Percent(1.0), - height: Val::Percent(1.0), - }, - border: Rect { - bottom: Val::Px(5.0), - start: Val::Px(5.0), - ..Default::default() - }, + size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), align_items: AlignItems::FlexEnd, ..Default::default() }, - material: materials.add(Color::rgb(0.8, 0.02, 0.02).into()), + material: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), ..Default::default() }) .with_children(|parent| { + // text parent.spawn(TextComponents { style: Style { - size: Size { - width: Val::Px(100.0), - height: Val::Px(30.0), + size: Size::new(Val::Px(100.0), Val::Px(30.0)), + margin: Rect { + left: Val::Px(5.0), + top: Val::Px(5.0), + ..Default::default() }, ..Default::default() }, @@ -102,153 +87,159 @@ fn setup( // right vertical fill .spawn(NodeComponents { style: Style { - size: Size { - width: Val::Px(100.0), - height: Val::Percent(1.0), - }, - border: Rect { - start: Val::Px(10.0), - end: Val::Px(10.0), - top: Val::Px(10.0), - bottom: Val::Px(10.0), - }, + size: Size::new(Val::Px(200.0), Val::Percent(100.0)), ..Default::default() }, material: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), ..Default::default() }) - // // left vertical fill - // .spawn(NodeComponents { - // style: Style { - // size: Size { - // width: Val::Percent(0.20), - // height: Val::Percent(0.20), - // }, - // justify_content: JustifyContent::FlexEnd, - // align_items: AlignItems::FlexEnd, - // ..Default::default() - // }, - // material: materials.add(Color::rgb(0.02, 0.8, 0.02).into()), - // ..Default::default() - // }) - // .with_children(|parent| { - // parent.spawn(NodeComponents { - // style: Style { - // size: Size { - // width: Val::Percent(0.50), - // height: Val::Percent(0.50), - // }, - // justify_content: JustifyContent::FlexEnd, - // align_items: AlignItems::FlexEnd, - // ..Default::default() - // }, - // material: materials.add(Color::rgb(0.8, 0.02, 0.02).into()), - // ..Default::default() - // }); - // }); - // // right vertical fill - // .spawn(NodeComponents { - // node: Node::new(Anchors::RIGHT_FULL, Margins::new(10.0, 100.0, 100.0, 100.0)), - // material: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), - // ..Default::default() - // }) - // // render order test: reddest in the back, whitest in the front - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(75.0, 60.0), - // Anchors::CENTER, - // Margins::new(0.0, 100.0, 0.0, 100.0), - // ), - // material: materials.add(Color::rgb(1.0, 0.0, 0.0).into()), - // ..Default::default() - // }) - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(50.0, 35.0), - // Anchors::CENTER, - // Margins::new(0.0, 100.0, 0.0, 100.0), - // ), - // material: materials.add(Color::rgb(1.0, 0.3, 0.3).into()), - // ..Default::default() - // }) - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(100.0, 85.0), - // Anchors::CENTER, - // Margins::new(0.0, 100.0, 0.0, 100.0), - // ), - // material: materials.add(Color::rgb(1.0, 0.5, 0.5).into()), - // ..Default::default() - // }) - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(150.0, 135.0), - // Anchors::CENTER, - // Margins::new(0.0, 100.0, 0.0, 100.0), - // ), - // material: materials.add(Color::rgb(1.0, 0.7, 0.7).into()), - // ..Default::default() - // }) - // // parenting - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(210.0, 0.0), - // Anchors::BOTTOM_LEFT, - // Margins::new(0.0, 200.0, 10.0, 210.0), - // ), - // material: materials.add(Color::rgb(0.1, 0.1, 1.0).into()), - // ..Default::default() - // }) - // .with_children(|parent| { - // parent.spawn(NodeComponents { - // node: Node::new(Anchors::FULL, Margins::new(20.0, 20.0, 20.0, 20.0)), - // material: materials.add(Color::rgb(0.6, 0.6, 1.0).into()), - // ..Default::default() - // }); - // }) - // // alpha test - // .spawn(NodeComponents { - // node: Node::positioned( - // Vec2::new(200.0, 185.0), - // Anchors::CENTER, - // Margins::new(0.0, 100.0, 0.0, 100.0), - // ), - // material: materials.add(Color::rgba(1.0, 0.9, 0.9, 0.4).into()), - // draw: Draw { - // is_transparent: true, - // ..Default::default() - // }, - // ..Default::default() - // }) - // // texture - // .spawn(NodeComponents { - // node: Node::new( - // Anchors::CENTER_TOP, - // Margins::new(-250.0, 250.0, 510.0 * aspect, 10.0), - // ), - // material: materials.add(ColorMaterial::texture(texture_handle)), - // draw: Draw { - // is_transparent: true, - // ..Default::default() - // }, - // ..Default::default() - // }); + // Absolute positioning .spawn(NodeComponents { style: Style { - size: Size { - width: Val::Px(100.0), - height: Val::Px(100.0), - }, - border: Rect { - start: Val::Px(10.0), - end: Val::Px(10.0), - top: Val::Px(10.0), + size: Size::new(Val::Px(200.0), Val::Px(200.0)), + position_type: PositionType::Absolute, + position: Rect { + left: Val::Px(210.0), bottom: Val::Px(10.0), + ..Default::default() }, + border: Rect::all(Val::Px(10.0)), ..Default::default() }, - material: materials.add(Color::rgb(1.0, 0.0, 0.0).into()), + material: materials.add(Color::rgb(0.1, 0.1, 1.0).into()), ..Default::default() + }) + .with_children(|parent| { + parent.spawn(NodeComponents { + style: Style { + size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), + ..Default::default() + }, + material: materials.add(Color::rgb(0.6, 0.6, 1.0).into()), + ..Default::default() + }); + }) + // render order test: reddest in the back, whitest in the front (flex center) + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), + position_type: PositionType::Absolute, + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..Default::default() + }, + material: materials.add(Color::NONE.into()), + draw: Draw { + is_transparent: true, + ..Default::default() + }, + ..Default::default() + }) + .with_children(|parent| { + parent + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Px(100.0), Val::Px(100.0)), + ..Default::default() + }, + material: materials.add(Color::rgb(1.0, 0.0, 0.0).into()), + ..Default::default() + }) + .with_children(|parent| { + parent + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Px(100.0), Val::Px(100.0)), + position_type: PositionType::Absolute, + position: Rect { + left: Val::Px(20.0), + bottom: Val::Px(20.0), + ..Default::default() + }, + ..Default::default() + }, + material: materials.add(Color::rgb(1.0, 0.3, 0.3).into()), + ..Default::default() + }) + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Px(100.0), Val::Px(100.0)), + position_type: PositionType::Absolute, + position: Rect { + left: Val::Px(40.0), + bottom: Val::Px(40.0), + ..Default::default() + }, + ..Default::default() + }, + material: materials.add(Color::rgb(1.0, 0.5, 0.5).into()), + ..Default::default() + }) + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Px(100.0), Val::Px(100.0)), + position_type: PositionType::Absolute, + position: Rect { + left: Val::Px(60.0), + bottom: Val::Px(60.0), + ..Default::default() + }, + ..Default::default() + }, + material: materials.add(Color::rgb(1.0, 0.7, 0.7).into()), + ..Default::default() + }) + // alpha test + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Px(100.0), Val::Px(100.0)), + position_type: PositionType::Absolute, + position: Rect { + left: Val::Px(80.0), + bottom: Val::Px(80.0), + ..Default::default() + }, + ..Default::default() + }, + material: materials.add(Color::rgba(1.0, 0.9, 0.9, 0.4).into()), + draw: Draw { + is_transparent: true, + ..Default::default() + }, + ..Default::default() + }); + }); + }) + // bevy logo (flex center) + .spawn(NodeComponents { + style: Style { + size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), + position_type: PositionType::Absolute, + justify_content: JustifyContent::Center, + align_items: AlignItems::FlexEnd, + ..Default::default() + }, + material: materials.add(Color::NONE.into()), + draw: Draw { + is_transparent: true, + ..Default::default() + }, + ..Default::default() + }) + .with_children(|parent| { + // bevy logo (image) + parent.spawn(NodeComponents { + style: Style { + min_size: Size::new(Val::Px(500.0), Val::Px(500.0 * aspect)), + ..Default::default() + }, + material: materials.add(ColorMaterial::texture(texture_handle)), + draw: Draw { + is_transparent: true, + ..Default::default() + }, + ..Default::default() + }); }); }); } diff --git a/examples/ui/ui_bench.rs b/examples/ui/ui_bench.rs index ad657661ba..e23f9e3c8e 100644 --- a/examples/ui/ui_bench.rs +++ b/examples/ui/ui_bench.rs @@ -16,7 +16,7 @@ fn placement_system( for (mut style, material_handle) in &mut query.iter() { let material = materials.get(&material_handle).unwrap(); if material.color.r > 0.2 { - style.position.start += 0.1 * time.delta_seconds; + style.position.left += 0.1 * time.delta_seconds; } } } @@ -37,8 +37,8 @@ fn setup(mut commands: Commands, mut materials: ResMut>) { }, position_type: PositionType::Absolute, position: Rect { - start: Val::Px(75.0 + cur.x()), - top: Val::Px(75.0 + cur.y()), + left: Val::Px(75.0 + cur.x()), + bottom: Val::Px(75.0 + cur.y()), ..Default::default() }, ..Default::default()