Show embedded scrollbars only when necessary in scrollable
This commit is contained in:
parent
7a81e638a3
commit
f78a87c409
3 changed files with 100 additions and 50 deletions
|
|
@ -426,55 +426,104 @@ where
|
|||
renderer: &Renderer,
|
||||
limits: &layout::Limits,
|
||||
) -> layout::Node {
|
||||
let (right_padding, bottom_padding) = match self.direction {
|
||||
let mut layout = |right_padding, bottom_padding| {
|
||||
layout::padded(
|
||||
limits,
|
||||
self.width,
|
||||
self.height,
|
||||
Padding {
|
||||
right: right_padding,
|
||||
bottom: bottom_padding,
|
||||
..Padding::ZERO
|
||||
},
|
||||
|limits| {
|
||||
let child_limits = layout::Limits::new(
|
||||
Size::new(limits.min().width, limits.min().height),
|
||||
Size::new(
|
||||
if self.direction.horizontal().is_some() {
|
||||
f32::INFINITY
|
||||
} else {
|
||||
limits.max().width
|
||||
},
|
||||
if self.direction.vertical().is_some() {
|
||||
f32::INFINITY
|
||||
} else {
|
||||
limits.max().height
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
self.content.as_widget().layout(
|
||||
&mut tree.children[0],
|
||||
renderer,
|
||||
&child_limits,
|
||||
)
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
match self.direction {
|
||||
Direction::Vertical(Scrollbar {
|
||||
width,
|
||||
margin,
|
||||
spacing: Some(spacing),
|
||||
..
|
||||
}) => (width + margin * 2.0 + spacing, 0.0),
|
||||
Direction::Horizontal(Scrollbar {
|
||||
})
|
||||
| Direction::Horizontal(Scrollbar {
|
||||
width,
|
||||
margin,
|
||||
spacing: Some(spacing),
|
||||
..
|
||||
}) => (0.0, width + margin * 2.0 + spacing),
|
||||
_ => (0.0, 0.0),
|
||||
};
|
||||
}) => {
|
||||
let is_vertical =
|
||||
matches!(self.direction, Direction::Vertical(_));
|
||||
|
||||
layout::padded(
|
||||
limits,
|
||||
self.width,
|
||||
self.height,
|
||||
Padding {
|
||||
right: right_padding,
|
||||
bottom: bottom_padding,
|
||||
..Padding::ZERO
|
||||
},
|
||||
|limits| {
|
||||
let child_limits = layout::Limits::new(
|
||||
Size::new(limits.min().width, limits.min().height),
|
||||
Size::new(
|
||||
if self.direction.horizontal().is_some() {
|
||||
f32::INFINITY
|
||||
} else {
|
||||
limits.max().width
|
||||
},
|
||||
if self.direction.vertical().is_some() {
|
||||
f32::INFINITY
|
||||
} else {
|
||||
limits.max().height
|
||||
},
|
||||
),
|
||||
let padding = width + margin * 2.0 + spacing;
|
||||
let state = tree.state.downcast_mut::<State>();
|
||||
|
||||
let status_quo = layout(
|
||||
if is_vertical && state.is_scrollbar_visible {
|
||||
padding
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
if !is_vertical && state.is_scrollbar_visible {
|
||||
padding
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
);
|
||||
|
||||
self.content.as_widget().layout(
|
||||
&mut tree.children[0],
|
||||
renderer,
|
||||
&child_limits,
|
||||
)
|
||||
},
|
||||
)
|
||||
let is_scrollbar_visible = if is_vertical {
|
||||
status_quo.children()[0].size().height
|
||||
> status_quo.size().height
|
||||
} else {
|
||||
status_quo.children()[0].size().width
|
||||
> status_quo.size().width
|
||||
};
|
||||
|
||||
if state.is_scrollbar_visible == is_scrollbar_visible {
|
||||
status_quo
|
||||
} else {
|
||||
log::trace!("Scrollbar status quo has changed");
|
||||
state.is_scrollbar_visible = is_scrollbar_visible;
|
||||
|
||||
layout(
|
||||
if is_vertical && state.is_scrollbar_visible {
|
||||
padding
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
if !is_vertical && state.is_scrollbar_visible {
|
||||
padding
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => layout(0.0, 0.0),
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(
|
||||
|
|
@ -1354,6 +1403,7 @@ struct State {
|
|||
keyboard_modifiers: keyboard::Modifiers,
|
||||
last_notified: Option<Viewport>,
|
||||
last_scrolled: Option<Instant>,
|
||||
is_scrollbar_visible: bool,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
|
|
@ -1367,6 +1417,7 @@ impl Default for State {
|
|||
keyboard_modifiers: keyboard::Modifiers::default(),
|
||||
last_notified: None,
|
||||
last_scrolled: None,
|
||||
is_scrollbar_visible: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1626,13 +1677,13 @@ impl Scrollbars {
|
|||
) -> Self {
|
||||
let translation = state.translation(direction, bounds, content_bounds);
|
||||
|
||||
let show_scrollbar_x = direction.horizontal().filter(|scrollbar| {
|
||||
scrollbar.spacing.is_some() || content_bounds.width > bounds.width
|
||||
});
|
||||
let show_scrollbar_x = direction
|
||||
.horizontal()
|
||||
.filter(|_scrollbar| content_bounds.width > bounds.width);
|
||||
|
||||
let show_scrollbar_y = direction.vertical().filter(|scrollbar| {
|
||||
scrollbar.spacing.is_some() || content_bounds.height > bounds.height
|
||||
});
|
||||
let show_scrollbar_y = direction
|
||||
.vertical()
|
||||
.filter(|_scrollbar| content_bounds.height > bounds.height);
|
||||
|
||||
let y_scrollbar = if let Some(vertical) = show_scrollbar_y {
|
||||
let Scrollbar {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue