Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Change UI coordinate system to have origin at top left corner #6000

Closed
wants to merge 13 commits into from
Closed
9 changes: 5 additions & 4 deletions crates/bevy_text/src/glyph_brush.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,17 @@ impl GlyphBrush {
})
.collect::<Result<Vec<_>, _>>()?;

let mut max_y = std::f32::MIN;
let mut min_x = std::f32::MAX;
let mut min_y = std::f32::MAX;
for sg in &glyphs {
let glyph = &sg.glyph;

let scaled_font = sections_data[sg.section_index].3;
max_y = max_y.max(glyph.position.y - scaled_font.descent());
min_x = min_x.min(glyph.position.x);
min_y = min_y.min(glyph.position.y - scaled_font.ascent());
}
max_y = max_y.floor();
min_x = min_x.floor();
min_y = min_y.floor();

let mut positioned_glyphs = Vec::new();
for sg in glyphs {
Expand Down Expand Up @@ -119,7 +120,7 @@ impl GlyphBrush {
let size = Vec2::new(glyph_rect.width(), glyph_rect.height());

let x = bounds.min.x + size.x / 2.0 - min_x;
let y = max_y - bounds.max.y + size.y / 2.0;
let y = bounds.min.y + size.y / 2.0 - min_y;
let position = adjust.position(Vec2::new(x, y));

positioned_glyphs.push(PositionedGlyph {
Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_ui/src/flex/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ pub fn from_rect(
taffy::geometry::Rect {
start: from_val(scale_factor, rect.left),
end: from_val(scale_factor, rect.right),
// NOTE: top and bottom are intentionally flipped. stretch has a flipped y-axis
top: from_val(scale_factor, rect.bottom),
bottom: from_val(scale_factor, rect.top),
top: from_val(scale_factor, rect.top),
bottom: from_val(scale_factor, rect.bottom),
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This crate contains Bevy's UI system, which can be used to create UI for both 2D and 3D games
//! # Basic usage
//! Spawn UI elements with [`entity::ButtonBundle`], [`entity::ImageBundle`], [`entity::TextBundle`] and [`entity::NodeBundle`]
//! This UI is laid out with the Flexbox paradigm (see <https://cssreference.io/flexbox/> ) except the vertical axis is inverted
//! This UI is laid out with the Flexbox paradigm (see <https://cssreference.io/flexbox/>)
mod flex;
mod focus;
mod geometry;
Expand Down
30 changes: 13 additions & 17 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use bevy_ecs::prelude::*;
use bevy_math::{Mat4, Rect, UVec4, Vec2, Vec3, Vec4Swizzles};
use bevy_reflect::TypeUuid;
use bevy_render::{
camera::{Camera, CameraProjection, OrthographicProjection, WindowOrigin},
camera::Camera,
color::Color,
render_asset::RenderAssets,
render_graph::{RenderGraph, RunGraphOnViewNode, SlotInfo, SlotType},
Expand Down Expand Up @@ -243,15 +243,12 @@ pub fn extract_default_ui_camera_view<T: Component>(
camera.physical_viewport_rect(),
camera.physical_viewport_size(),
) {
let mut projection = OrthographicProjection {
far: UI_CAMERA_FAR,
window_origin: WindowOrigin::BottomLeft,
..Default::default()
};
projection.update(logical_size.x, logical_size.y);
// use a projection matrix with the origin in the top left instead of the bottom left that comes with OrthographicProjection
let projection_matrix =
Mat4::orthographic_rh(0.0, logical_size.x, logical_size.y, 0.0, 0.0, UI_CAMERA_FAR);
mahulst marked this conversation as resolved.
Show resolved Hide resolved
let default_camera_view = commands
.spawn(ExtractedView {
projection: projection.get_projection_matrix(),
projection: projection_matrix,
transform: GlobalTransform::from_xyz(
0.0,
0.0,
Expand Down Expand Up @@ -464,24 +461,23 @@ pub fn prepare_uinodes(
}
}

// Clip UVs (Note: y is reversed in UV space)
let atlas_extent = extracted_uinode.atlas_size.unwrap_or(uinode_rect.max);
let uvs = [
Vec2::new(
uinode_rect.min.x + positions_diff[0].x,
uinode_rect.max.y - positions_diff[0].y,
),
Vec2::new(
uinode_rect.max.x + positions_diff[1].x,
uinode_rect.max.y - positions_diff[1].y,
uinode_rect.min.x + positions_diff[3].x,
uinode_rect.min.y - positions_diff[3].y,
),
Vec2::new(
uinode_rect.max.x + positions_diff[2].x,
uinode_rect.min.y - positions_diff[2].y,
),
Vec2::new(
uinode_rect.min.x + positions_diff[3].x,
uinode_rect.min.y - positions_diff[3].y,
uinode_rect.max.x + positions_diff[1].x,
uinode_rect.max.y - positions_diff[1].y,
),
Vec2::new(
uinode_rect.min.x + positions_diff[0].x,
uinode_rect.max.y - positions_diff[0].y,
),
]
.map(|pos| pos / atlas_extent);
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,11 @@ pub enum FlexDirection {
/// Same way as text direction along the main axis
#[default]
Row,
/// Flex from bottom to top
/// Flex from top to bottom
Column,
/// Opposite way as text direction along the main axis
RowReverse,
/// Flex from top to bottom
/// Flex from bottom to top
ColumnReverse,
}

Expand Down
14 changes: 3 additions & 11 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,9 @@ fn change_window(
}
bevy_window::WindowCommand::SetCursorPosition { position } => {
let window = winit_windows.get_window(id).unwrap();
let inner_size = window.inner_size().to_logical::<f32>(window.scale_factor());

window
.set_cursor_position(LogicalPosition::new(
position.x,
inner_size.height - position.y,
))
.set_cursor_position(LogicalPosition::new(position.x, position.y))
.unwrap_or_else(|e| error!("Unable to set cursor position: {}", e));
}
bevy_window::WindowCommand::SetMaximized { maximized } => {
Expand Down Expand Up @@ -431,13 +428,8 @@ pub fn winit_runner_with(mut app: App) {
}
WindowEvent::CursorMoved { position, .. } => {
let mut cursor_moved_events = world.resource_mut::<Events<CursorMoved>>();
let winit_window = winit_windows.get_window(window_id).unwrap();
let inner_size = winit_window.inner_size();

// move origin to bottom left
let y_position = inner_size.height as f64 - position.y;

let physical_position = DVec2::new(position.x, y_position);
let physical_position = DVec2::new(position.x, position.y);
window
.update_cursor_physical_position_from_backend(Some(physical_position));

Expand Down
13 changes: 6 additions & 7 deletions examples/games/game_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,8 @@ mod game {
style: Style {
// This will center the current node
margin: UiRect::all(Val::Auto),
// This will display its children in a column, from top to bottom. Unlike
// in Flexbox, Bevy origin is on bottom left, so the vertical axis is reversed
flex_direction: FlexDirection::ColumnReverse,
// This will display its children in a column, from top to bottom
flex_direction: FlexDirection::Column,
// `align_items` will align children on the cross axis. Here the main axis is
// vertical (column), so the cross axis is horizontal. This will center the
// children
Expand Down Expand Up @@ -420,7 +419,7 @@ mod menu {
NodeBundle {
style: Style {
margin: UiRect::all(Val::Auto),
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
align_items: AlignItems::Center,
..default()
},
Expand Down Expand Up @@ -533,7 +532,7 @@ mod menu {
NodeBundle {
style: Style {
margin: UiRect::all(Val::Auto),
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
align_items: AlignItems::Center,
..default()
},
Expand Down Expand Up @@ -587,7 +586,7 @@ mod menu {
NodeBundle {
style: Style {
margin: UiRect::all(Val::Auto),
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
align_items: AlignItems::Center,
..default()
},
Expand Down Expand Up @@ -678,7 +677,7 @@ mod menu {
NodeBundle {
style: Style {
margin: UiRect::all(Val::Auto),
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
align_items: AlignItems::Center,
..default()
},
Expand Down
31 changes: 23 additions & 8 deletions examples/ui/font_atlas_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,27 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResM
let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");
state.handle = font_handle.clone();
commands.spawn(Camera2dBundle::default());
commands.spawn(TextBundle::from_section(
"a",
TextStyle {
font: font_handle,
font_size: 60.0,
color: Color::YELLOW,
},
));
commands
.spawn(NodeBundle {
background_color: Color::NONE.into(),
style: Style {
position_type: PositionType::Absolute,
position: UiRect {
bottom: Val::Px(0.0),
..default()
},
..default()
},
..default()
})
.with_children(|parent| {
parent.spawn(TextBundle::from_section(
"a",
TextStyle {
font: font_handle,
font_size: 60.0,
color: Color::YELLOW,
},
));
});
}
7 changes: 1 addition & 6 deletions examples/ui/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.with_text_alignment(TextAlignment::TOP_CENTER)
// Set the style of the TextBundle itself.
.with_style(Style {
align_self: AlignSelf::FlexEnd,
mahulst marked this conversation as resolved.
Show resolved Hide resolved
position_type: PositionType::Absolute,
position: UiRect {
bottom: Val::Px(5.0),
Expand Down Expand Up @@ -72,11 +71,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
font_size: 60.0,
color: Color::GOLD,
}),
])
.with_style(Style {
align_self: AlignSelf::FlexEnd,
..default()
}),
]),
FpsText,
));
}
Expand Down
3 changes: 0 additions & 3 deletions examples/ui/text_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ fn infotext_system(mut commands: Commands, asset_server: Res<AssetServer>) {
},
)
.with_style(Style {
align_self: AlignSelf::FlexEnd,
position_type: PositionType::Absolute,
position: UiRect {
top: Val::Px(5.0),
Expand All @@ -55,7 +54,6 @@ fn infotext_system(mut commands: Commands, asset_server: Res<AssetServer>) {
)
.with_text_alignment(TextAlignment::CENTER)
.with_style(Style {
align_self: AlignSelf::FlexEnd,
position_type: PositionType::Absolute,
position: UiRect {
top: Val::Px(5.0),
Expand Down Expand Up @@ -115,7 +113,6 @@ fn infotext_system(mut commands: Commands, asset_server: Res<AssetServer>) {
),
])
.with_style(Style {
align_self: AlignSelf::FlexEnd,
position_type: PositionType::Absolute,
position: UiRect {
bottom: Val::Px(5.0),
Expand Down
14 changes: 6 additions & 8 deletions examples/ui/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.spawn(NodeBundle {
style: Style {
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
align_items: AlignItems::FlexEnd,
..default()
},
background_color: Color::rgb(0.15, 0.15, 0.15).into(),
Expand Down Expand Up @@ -77,7 +76,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
parent
.spawn(NodeBundle {
style: Style {
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Center,
size: Size::new(Val::Px(200.0), Val::Percent(100.0)),
..default()
Expand Down Expand Up @@ -110,7 +109,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
parent
.spawn(NodeBundle {
style: Style {
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
align_self: AlignSelf::Center,
size: Size::new(Val::Percent(100.0), Val::Percent(50.0)),
overflow: Overflow::Hidden,
Expand All @@ -125,7 +124,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
.spawn((
NodeBundle {
style: Style {
flex_direction: FlexDirection::ColumnReverse,
flex_direction: FlexDirection::Column,
flex_grow: 1.0,
max_size: Size::UNDEFINED,
..default()
Expand Down Expand Up @@ -163,7 +162,6 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
});
});
});
// absolute positioning
parent
.spawn(NodeBundle {
style: Style {
Expand Down Expand Up @@ -280,7 +278,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
position_type: PositionType::Absolute,
justify_content: JustifyContent::Center,
align_items: AlignItems::FlexEnd,
align_items: AlignItems::FlexStart,
mahulst marked this conversation as resolved.
Show resolved Hide resolved
..default()
},
background_color: Color::NONE.into(),
Expand Down Expand Up @@ -322,8 +320,8 @@ fn mouse_scroll(
MouseScrollUnit::Line => mouse_wheel_event.y * 20.,
MouseScrollUnit::Pixel => mouse_wheel_event.y,
};
scrolling_list.position += dy;
scrolling_list.position = scrolling_list.position.clamp(-max_scroll, 0.);
scrolling_list.position -= dy;
scrolling_list.position = scrolling_list.position.clamp(0., max_scroll);
style.position.top = Val::Px(scrolling_list.position);
}
}
Expand Down