Improve layout when two scrollbars are shown

This commit is contained in:
MrSubidubi 2025-08-24 21:53:15 +02:00
parent 1f2d18e691
commit a067729525

View file

@ -984,67 +984,78 @@ impl<S: ScrollbarVisibilitySetting, T: ScrollableHandle> Element for ScrollbarEl
.not() .not()
.then(|| ScrollbarPrepaintState { .then(|| ScrollbarPrepaintState {
parent_bounds: bounds, parent_bounds: bounds,
thumbs: self thumbs: {
.state let thumb_ranges = self.state.read(cx).thumb_ranges().collect::<Vec<_>>();
.read(cx) let width = self.state.read(cx).width.to_pixels();
.thumb_ranges()
.map(|(axis, thumb_range, reserved_space)| {
let track_anchor = match axis {
ScrollbarAxis::Horizontal => Corner::BottomLeft,
ScrollbarAxis::Vertical => Corner::TopRight,
};
let Bounds { origin, size } = Bounds::from_corner_and_size(
track_anchor,
bounds
.corner(track_anchor)
.apply_along(axis.invert(), |corner| corner - SCROLLBAR_PADDING),
bounds.size.apply_along(axis.invert(), |_| {
self.state.read(cx).width.to_pixels()
}),
);
let scroll_track_bounds = Bounds::new(self.origin + origin, size);
let padded_bounds = scroll_track_bounds.extend(match axis { let additional_padding = if thumb_ranges.len() == 2 {
ScrollbarAxis::Horizontal => Edges { width + SCROLLBAR_PADDING
right: -SCROLLBAR_PADDING, } else {
left: -SCROLLBAR_PADDING, Pixels::ZERO
..Default::default() };
},
ScrollbarAxis::Vertical => Edges {
top: -SCROLLBAR_PADDING,
bottom: -SCROLLBAR_PADDING,
..Default::default()
},
});
let thumb_offset = thumb_range.start * padded_bounds.size.along(axis); thumb_ranges
let thumb_end = thumb_range.end * padded_bounds.size.along(axis); .into_iter()
.map(|(axis, thumb_range, reserved_space)| {
let track_anchor = match axis {
ScrollbarAxis::Horizontal => Corner::BottomLeft,
ScrollbarAxis::Vertical => Corner::TopRight,
};
let Bounds { origin, size } = Bounds::from_corner_and_size(
track_anchor,
bounds
.corner(track_anchor)
.apply_along(axis.invert(), |corner| {
corner - SCROLLBAR_PADDING
}),
bounds.size.apply_along(axis.invert(), |_| width),
);
let scroll_track_bounds = Bounds::new(self.origin + origin, size);
let thumb_bounds = Bounds::new( let padded_bounds = scroll_track_bounds.extend(match axis {
padded_bounds ScrollbarAxis::Horizontal => Edges {
.origin right: -SCROLLBAR_PADDING,
.apply_along(axis, |origin| origin + thumb_offset), left: -SCROLLBAR_PADDING,
padded_bounds ..Default::default()
.size
.apply_along(axis, |_| thumb_end - thumb_offset),
);
ScrollbarLayout {
thumb_bounds,
track_bounds: padded_bounds,
axis,
cursor_hitbox: window.insert_hitbox(
if reserved_space.needs_scroll_track() {
padded_bounds
} else {
thumb_bounds
}, },
HitboxBehavior::BlockMouseExceptScroll, ScrollbarAxis::Vertical => Edges {
), top: -SCROLLBAR_PADDING,
reserved_space, bottom: -SCROLLBAR_PADDING,
} ..Default::default()
}) },
.collect(), });
let available_space =
padded_bounds.size.along(axis) - additional_padding;
let thumb_offset = thumb_range.start * available_space;
let thumb_end = thumb_range.end * available_space;
let thumb_bounds = Bounds::new(
padded_bounds
.origin
.apply_along(axis, |origin| origin + thumb_offset),
padded_bounds
.size
.apply_along(axis, |_| thumb_end - thumb_offset),
);
ScrollbarLayout {
thumb_bounds,
track_bounds: padded_bounds,
axis,
cursor_hitbox: window.insert_hitbox(
if reserved_space.needs_scroll_track() {
padded_bounds
} else {
thumb_bounds
},
HitboxBehavior::BlockMouseExceptScroll,
),
reserved_space,
}
})
.collect()
},
}) })
} }