Skip to content

Commit 75c9e7a

Browse files
ickshonpemockersf
authored andcommitted
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.
1 parent 54733e8 commit 75c9e7a

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

crates/bevy_ui/src/layout/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,14 +433,20 @@ with UI components as a child of an entity without UI components, your UI layout
433433

434434
let content_size = Vec2::new(layout.content_size.width, layout.content_size.height);
435435
let max_possible_offset = (content_size - layout_size).max(Vec2::ZERO);
436-
let clamped_scroll_position = scroll_position.clamp(Vec2::ZERO, max_possible_offset);
436+
let clamped_scroll_position = scroll_position.clamp(
437+
Vec2::ZERO,
438+
max_possible_offset * inverse_target_scale_factor,
439+
);
437440

438441
if clamped_scroll_position != scroll_position {
439442
commands
440443
.entity(entity)
441-
.insert(ScrollPosition::from(&clamped_scroll_position));
444+
.insert(ScrollPosition::from(clamped_scroll_position));
442445
}
443446

447+
let physical_scroll_position =
448+
(clamped_scroll_position / inverse_target_scale_factor).round();
449+
444450
for child_uinode in ui_children.iter_ui_children(entity) {
445451
update_uinode_geometry_recursive(
446452
commands,
@@ -451,7 +457,7 @@ with UI components as a child of an entity without UI components, your UI layout
451457
ui_children,
452458
inverse_target_scale_factor,
453459
layout_size,
454-
clamped_scroll_position,
460+
physical_scroll_position,
455461
);
456462
}
457463
}

crates/bevy_ui/src/ui_node.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ impl Default for ComputedNode {
237237
#[derive(Component, Debug, Clone, Reflect)]
238238
#[reflect(Component, Default)]
239239
pub struct ScrollPosition {
240-
/// How far across the node is scrolled, in pixels. (0 = not scrolled / scrolled to right)
240+
/// How far across the node is scrolled, in logical pixels. (0 = not scrolled / scrolled to right)
241241
pub offset_x: f32,
242-
/// How far down the node is scrolled, in pixels. (0 = not scrolled / scrolled to top)
242+
/// How far down the node is scrolled, in logical pixels. (0 = not scrolled / scrolled to top)
243243
pub offset_y: f32,
244244
}
245245

@@ -262,8 +262,8 @@ impl From<&ScrollPosition> for Vec2 {
262262
}
263263
}
264264

265-
impl From<&Vec2> for ScrollPosition {
266-
fn from(vec: &Vec2) -> Self {
265+
impl From<Vec2> for ScrollPosition {
266+
fn from(vec: Vec2) -> Self {
267267
ScrollPosition {
268268
offset_x: vec.x,
269269
offset_y: vec.y,

0 commit comments

Comments
 (0)