ui: fix examples, flip fix stretch axis incompatibility, ergonomics

This commit is contained in:
Carter Anderson 2020-07-27 19:12:48 -07:00
parent 3d5e7e54f3
commit 1f006c348d
6 changed files with 209 additions and 225 deletions

View File

@ -24,17 +24,28 @@ impl<T: Default> Default for Size<T> {
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
pub struct Rect<T> { pub struct Rect<T> {
pub start: T, pub left: T,
pub end: T, pub right: T,
pub top: T, pub top: T,
pub bottom: T, pub bottom: T,
} }
impl<T> Rect<T> {
pub fn all(value: T) -> Self where T: Clone{
Rect {
left: value.clone(),
right: value.clone(),
top: value.clone(),
bottom: value,
}
}
}
impl<T: Default> Default for Rect<T> { impl<T: Default> Default for Rect<T> {
fn default() -> Self { fn default() -> Self {
Self { Self {
start: Default::default(), left: Default::default(),
end: Default::default(), right: Default::default(),
top: Default::default(), top: Default::default(),
bottom: Default::default(), bottom: Default::default(),
} }

View File

@ -9,10 +9,11 @@ where
T: From<U>, T: From<U>,
{ {
stretch::geometry::Rect { stretch::geometry::Rect {
start: rect.start.into(), start: rect.left.into(),
end: rect.end.into(), end: rect.right.into(),
top: rect.top.into(), // NOTE: top and bottom are intentionally flipped. stretch has a flipped y-axis
bottom: rect.bottom.into(), top: rect.bottom.into(),
bottom: rect.top.into(),
} }
} }
@ -61,7 +62,7 @@ impl From<Val> for stretch::style::Dimension {
fn from(val: Val) -> Self { fn from(val: Val) -> Self {
match val { match val {
Val::Auto => stretch::style::Dimension::Auto, 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::Px(value) => stretch::style::Dimension::Points(value),
Val::Undefined => stretch::style::Dimension::Undefined, Val::Undefined => stretch::style::Dimension::Undefined,
} }

View File

@ -88,7 +88,6 @@ pub fn winit_runner(mut app: App) {
.resources .resources
.get_mut::<Events<WindowCloseRequested>>() .get_mut::<Events<WindowCloseRequested>>()
.unwrap(); .unwrap();
let windows = app.resources.get_mut::<Windows>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap(); let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
window_close_requested_events.send(WindowCloseRequested { id: window_id }); window_close_requested_events.send(WindowCloseRequested { id: window_id });

View File

@ -87,64 +87,46 @@ fn button_system(
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut materials: ResMut<Assets<ColorMaterial>>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
button_materials: Res<ButtonMaterials>, button_materials: Res<ButtonMaterials>,
) { ) {
commands commands
// ui camera // ui camera
.spawn(UiCameraComponents::default()) .spawn(UiCameraComponents::default())
// wrapper component to center with flexbox .spawn(ButtonComponents {
.spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Px(150.0), Val::Px(70.0)),
width: Val::Percent(1.0), align_self: AlignSelf::Center,
height: Val::Percent(1.0), margin: Rect {
left: Val::Auto,
right: Val::Auto,
..Default::default()
}, },
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..Default::default() ..Default::default()
}, },
material: materials.add(Color::NONE.into()), material: button_materials.normal,
..Default::default() ..Default::default()
}) })
.with_children(|parent| { .with_children(|parent| {
parent parent.spawn(TextComponents {
.spawn(ButtonComponents { style: Style {
style: Style { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
size: Size { margin: Rect {
width: Val::Px(150.0), bottom: Val::Px(10.0),
height: Val::Px(70.0),
},
..Default::default() ..Default::default()
}, },
material: button_materials.normal,
..Default::default() ..Default::default()
}) },
.with_children(|parent| { text: Text {
parent.spawn(TextComponents { value: "Button".to_string(),
style: Style { font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(),
size: Size { style: TextStyle {
width: Val::Percent(1.0), font_size: 40.0,
height: Val::Percent(1.0), color: Color::rgb(0.8, 0.8, 0.8),
}, align: TextAlign::Center,
margin: Rect { },
top: Val::Px(10.0), },
..Default::default() ..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()
});
});
}); });
} }

View File

@ -13,12 +13,12 @@ fn setup(
mut textures: ResMut<Assets<Texture>>, mut textures: ResMut<Assets<Texture>>,
mut materials: ResMut<Assets<ColorMaterial>>, mut materials: ResMut<Assets<ColorMaterial>>,
) { ) {
// let texture_handle = asset_server let texture_handle = asset_server
// .load_sync(&mut textures, "assets/branding/bevy_logo_dark_big.png") .load_sync(&mut textures, "assets/branding/bevy_logo_dark_big.png")
// .unwrap(); .unwrap();
// let texture = textures.get(&texture_handle).unwrap(); let texture = textures.get(&texture_handle).unwrap();
// let aspect = texture.aspect(); let aspect = texture.aspect();
commands commands
// ui camera // ui camera
@ -26,10 +26,7 @@ fn setup(
// root node // root node
.spawn(NodeComponents { .spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
width: Val::Percent(1.0),
height: Val::Percent(1.0),
},
justify_content: JustifyContent::SpaceBetween, justify_content: JustifyContent::SpaceBetween,
..Default::default() ..Default::default()
}, },
@ -38,49 +35,37 @@ fn setup(
}) })
.with_children(|parent| { .with_children(|parent| {
parent parent
// left vertical fill // left vertical fill (border)
.spawn(NodeComponents { .spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Px(200.0), Val::Percent(100.0)),
width: Val::Px(200.0), border: Rect::all(Val::Px(2.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),
},
..Default::default() ..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() ..Default::default()
}) })
.with_children(|parent| { .with_children(|parent| {
parent parent
// left vertical fill (content)
.spawn(NodeComponents { .spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
width: Val::Percent(1.0),
height: Val::Percent(1.0),
},
border: Rect {
bottom: Val::Px(5.0),
start: Val::Px(5.0),
..Default::default()
},
align_items: AlignItems::FlexEnd, align_items: AlignItems::FlexEnd,
..Default::default() ..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() ..Default::default()
}) })
.with_children(|parent| { .with_children(|parent| {
// text
parent.spawn(TextComponents { parent.spawn(TextComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Px(100.0), Val::Px(30.0)),
width: Val::Px(100.0), margin: Rect {
height: Val::Px(30.0), left: Val::Px(5.0),
top: Val::Px(5.0),
..Default::default()
}, },
..Default::default() ..Default::default()
}, },
@ -102,153 +87,159 @@ fn setup(
// right vertical fill // right vertical fill
.spawn(NodeComponents { .spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Px(200.0), Val::Percent(100.0)),
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),
},
..Default::default() ..Default::default()
}, },
material: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), material: materials.add(Color::rgb(0.02, 0.02, 0.02).into()),
..Default::default() ..Default::default()
}) })
// // left vertical fill // Absolute positioning
// .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()
// });
.spawn(NodeComponents { .spawn(NodeComponents {
style: Style { style: Style {
size: Size { size: Size::new(Val::Px(200.0), Val::Px(200.0)),
width: Val::Px(100.0), position_type: PositionType::Absolute,
height: Val::Px(100.0), position: Rect {
}, left: Val::Px(210.0),
border: Rect {
start: Val::Px(10.0),
end: Val::Px(10.0),
top: Val::Px(10.0),
bottom: Val::Px(10.0), bottom: Val::Px(10.0),
..Default::default()
}, },
border: Rect::all(Val::Px(10.0)),
..Default::default() ..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() ..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()
});
}); });
}); });
} }

View File

@ -16,7 +16,7 @@ fn placement_system(
for (mut style, material_handle) in &mut query.iter() { for (mut style, material_handle) in &mut query.iter() {
let material = materials.get(&material_handle).unwrap(); let material = materials.get(&material_handle).unwrap();
if material.color.r > 0.2 { 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<Assets<ColorMaterial>>) {
}, },
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
position: Rect { position: Rect {
start: Val::Px(75.0 + cur.x()), left: Val::Px(75.0 + cur.x()),
top: Val::Px(75.0 + cur.y()), bottom: Val::Px(75.0 + cur.y()),
..Default::default() ..Default::default()
}, },
..Default::default() ..Default::default()