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(),
|
Screen::End => self.end(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let content: Element<_> = column![screen, controls,]
|
let content: Element<_> =
|
||||||
.max_width(540)
|
column![screen, controls].max_width(540).spacing(20).into();
|
||||||
.spacing(20)
|
|
||||||
.padding(20)
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let scrollable = scrollable(center_x(if self.debug {
|
let scrollable = scrollable(center_x(if self.debug {
|
||||||
content.explain(Color::BLACK)
|
content.explain(Color::BLACK)
|
||||||
} else {
|
} else {
|
||||||
content
|
content
|
||||||
}));
|
}))
|
||||||
|
.spacing(10);
|
||||||
|
|
||||||
center_y(scrollable).into()
|
center_y(scrollable).padding(10).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_continue(&self) -> bool {
|
fn can_continue(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ impl WebSocket {
|
||||||
)
|
)
|
||||||
.id(MESSAGE_LOG.clone())
|
.id(MESSAGE_LOG.clone())
|
||||||
.height(Fill)
|
.height(Fill)
|
||||||
|
.spacing(10)
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -426,55 +426,104 @@ where
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
) -> layout::Node {
|
) -> 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 {
|
Direction::Vertical(Scrollbar {
|
||||||
width,
|
width,
|
||||||
margin,
|
margin,
|
||||||
spacing: Some(spacing),
|
spacing: Some(spacing),
|
||||||
..
|
..
|
||||||
}) => (width + margin * 2.0 + spacing, 0.0),
|
})
|
||||||
Direction::Horizontal(Scrollbar {
|
| Direction::Horizontal(Scrollbar {
|
||||||
width,
|
width,
|
||||||
margin,
|
margin,
|
||||||
spacing: Some(spacing),
|
spacing: Some(spacing),
|
||||||
..
|
..
|
||||||
}) => (0.0, width + margin * 2.0 + spacing),
|
}) => {
|
||||||
_ => (0.0, 0.0),
|
let is_vertical =
|
||||||
};
|
matches!(self.direction, Direction::Vertical(_));
|
||||||
|
|
||||||
layout::padded(
|
let padding = width + margin * 2.0 + spacing;
|
||||||
limits,
|
let state = tree.state.downcast_mut::<State>();
|
||||||
self.width,
|
|
||||||
self.height,
|
let status_quo = layout(
|
||||||
Padding {
|
if is_vertical && state.is_scrollbar_visible {
|
||||||
right: right_padding,
|
padding
|
||||||
bottom: bottom_padding,
|
} else {
|
||||||
..Padding::ZERO
|
0.0
|
||||||
},
|
},
|
||||||
|limits| {
|
if !is_vertical && state.is_scrollbar_visible {
|
||||||
let child_limits = layout::Limits::new(
|
padding
|
||||||
Size::new(limits.min().width, limits.min().height),
|
} else {
|
||||||
Size::new(
|
0.0
|
||||||
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(
|
let is_scrollbar_visible = if is_vertical {
|
||||||
&mut tree.children[0],
|
status_quo.children()[0].size().height
|
||||||
renderer,
|
> status_quo.size().height
|
||||||
&child_limits,
|
} 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(
|
fn operate(
|
||||||
|
|
@ -1354,6 +1403,7 @@ struct State {
|
||||||
keyboard_modifiers: keyboard::Modifiers,
|
keyboard_modifiers: keyboard::Modifiers,
|
||||||
last_notified: Option<Viewport>,
|
last_notified: Option<Viewport>,
|
||||||
last_scrolled: Option<Instant>,
|
last_scrolled: Option<Instant>,
|
||||||
|
is_scrollbar_visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for State {
|
impl Default for State {
|
||||||
|
|
@ -1367,6 +1417,7 @@ impl Default for State {
|
||||||
keyboard_modifiers: keyboard::Modifiers::default(),
|
keyboard_modifiers: keyboard::Modifiers::default(),
|
||||||
last_notified: None,
|
last_notified: None,
|
||||||
last_scrolled: None,
|
last_scrolled: None,
|
||||||
|
is_scrollbar_visible: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1626,13 +1677,13 @@ impl Scrollbars {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let translation = state.translation(direction, bounds, content_bounds);
|
let translation = state.translation(direction, bounds, content_bounds);
|
||||||
|
|
||||||
let show_scrollbar_x = direction.horizontal().filter(|scrollbar| {
|
let show_scrollbar_x = direction
|
||||||
scrollbar.spacing.is_some() || content_bounds.width > bounds.width
|
.horizontal()
|
||||||
});
|
.filter(|_scrollbar| content_bounds.width > bounds.width);
|
||||||
|
|
||||||
let show_scrollbar_y = direction.vertical().filter(|scrollbar| {
|
let show_scrollbar_y = direction
|
||||||
scrollbar.spacing.is_some() || content_bounds.height > bounds.height
|
.vertical()
|
||||||
});
|
.filter(|_scrollbar| content_bounds.height > bounds.height);
|
||||||
|
|
||||||
let y_scrollbar = if let Some(vertical) = show_scrollbar_y {
|
let y_scrollbar = if let Some(vertical) = show_scrollbar_y {
|
||||||
let Scrollbar {
|
let Scrollbar {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue