ScrollPosition
scale factor fix (#16617)
# Objective Scroll position uses physical coordinates. This means scrolling may go faster or slower depending on the scroll factor. Also the scrolled position will change when the scale factor changes. ## Solution In `ui_layout_system` convert `max_possible_offset` to logical coordinates before clamping the scroll position. Then convert the clamped scroll position to physical coordinates before propagating it to the node's children. ## Testing Look at the `scroll` example. On main if you change your display's scale factor the items displayed by the scrolling lists will change because `ScrollPosition`'s displacement values don't respect scale factor. With this PR the displacement will be scaled too, and the won't move.
This commit is contained in:
parent
54733e82ae
commit
75c9e7a198
@ -433,14 +433,20 @@ with UI components as a child of an entity without UI components, your UI layout
|
||||
|
||||
let content_size = Vec2::new(layout.content_size.width, layout.content_size.height);
|
||||
let max_possible_offset = (content_size - layout_size).max(Vec2::ZERO);
|
||||
let clamped_scroll_position = scroll_position.clamp(Vec2::ZERO, max_possible_offset);
|
||||
let clamped_scroll_position = scroll_position.clamp(
|
||||
Vec2::ZERO,
|
||||
max_possible_offset * inverse_target_scale_factor,
|
||||
);
|
||||
|
||||
if clamped_scroll_position != scroll_position {
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(ScrollPosition::from(&clamped_scroll_position));
|
||||
.insert(ScrollPosition::from(clamped_scroll_position));
|
||||
}
|
||||
|
||||
let physical_scroll_position =
|
||||
(clamped_scroll_position / inverse_target_scale_factor).round();
|
||||
|
||||
for child_uinode in ui_children.iter_ui_children(entity) {
|
||||
update_uinode_geometry_recursive(
|
||||
commands,
|
||||
@ -451,7 +457,7 @@ with UI components as a child of an entity without UI components, your UI layout
|
||||
ui_children,
|
||||
inverse_target_scale_factor,
|
||||
layout_size,
|
||||
clamped_scroll_position,
|
||||
physical_scroll_position,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -237,9 +237,9 @@ impl Default for ComputedNode {
|
||||
#[derive(Component, Debug, Clone, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct ScrollPosition {
|
||||
/// How far across the node is scrolled, in pixels. (0 = not scrolled / scrolled to right)
|
||||
/// How far across the node is scrolled, in logical pixels. (0 = not scrolled / scrolled to right)
|
||||
pub offset_x: f32,
|
||||
/// How far down the node is scrolled, in pixels. (0 = not scrolled / scrolled to top)
|
||||
/// How far down the node is scrolled, in logical pixels. (0 = not scrolled / scrolled to top)
|
||||
pub offset_y: f32,
|
||||
}
|
||||
|
||||
@ -262,8 +262,8 @@ impl From<&ScrollPosition> for Vec2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Vec2> for ScrollPosition {
|
||||
fn from(vec: &Vec2) -> Self {
|
||||
impl From<Vec2> for ScrollPosition {
|
||||
fn from(vec: Vec2) -> Self {
|
||||
ScrollPosition {
|
||||
offset_x: vec.x,
|
||||
offset_y: vec.y,
|
||||
|
Loading…
Reference in New Issue
Block a user