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
|
|
@ -168,19 +168,17 @@ impl Tour {
|
|||
Screen::End => self.end(),
|
||||
};
|
||||
|
||||
let content: Element<_> = column![screen, controls,]
|
||||
.max_width(540)
|
||||
.spacing(20)
|
||||
.padding(20)
|
||||
.into();
|
||||
let content: Element<_> =
|
||||
column![screen, controls].max_width(540).spacing(20).into();
|
||||
|
||||
let scrollable = scrollable(center_x(if self.debug {
|
||||
content.explain(Color::BLACK)
|
||||
} else {
|
||||
content
|
||||
}));
|
||||
}))
|
||||
.spacing(10);
|
||||
|
||||
center_y(scrollable).into()
|
||||
center_y(scrollable).padding(10).into()
|
||||
}
|
||||
|
||||
fn can_continue(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ impl WebSocket {
|
|||
)
|
||||
.id(MESSAGE_LOG.clone())
|
||||
.height(Fill)
|
||||
.spacing(10)
|
||||
.into()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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