Expose scrollable offset properly
This commit is contained in:
parent
719c073fc6
commit
09bd2c46c0
4 changed files with 44 additions and 26 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Align, Column, Justify, Length};
|
||||
use crate::{Align, Column, Justify, Length, Rectangle};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Scrollable<'a, Element> {
|
||||
|
|
@ -112,11 +112,35 @@ impl<'a, Element> Scrollable<'a, Element> {
|
|||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct State {
|
||||
pub offset: u32,
|
||||
offset: u32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
State::default()
|
||||
}
|
||||
|
||||
pub fn scroll(
|
||||
&mut self,
|
||||
delta_y: f32,
|
||||
bounds: Rectangle,
|
||||
content_bounds: Rectangle,
|
||||
) {
|
||||
if bounds.height >= content_bounds.height {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Configurable speed (?)
|
||||
self.offset = (self.offset as i32 - delta_y.round() as i32 * 15)
|
||||
.max(0)
|
||||
.min((content_bounds.height - bounds.height) as i32)
|
||||
as u32;
|
||||
}
|
||||
|
||||
pub fn offset(&self, bounds: Rectangle, content_bounds: Rectangle) -> u32 {
|
||||
let hidden_content =
|
||||
(content_bounds.height - bounds.height).round() as u32;
|
||||
|
||||
self.offset.min(hidden_content).max(0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use iced::{
|
||||
button, scrollable, Align, Application, Button, Color, Element, Image,
|
||||
Length, Scrollable, Text,
|
||||
button, scrollable, Align, Application, Button, Color, Column, Element,
|
||||
Image, Justify, Length, Scrollable, Text,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
|
|
@ -32,12 +32,7 @@ impl Application for Example {
|
|||
}
|
||||
|
||||
fn view(&mut self) -> Element<Message> {
|
||||
let content = Scrollable::new(&mut self.scroll)
|
||||
.width(Length::Fill)
|
||||
.max_width(Length::Units(600))
|
||||
.spacing(20)
|
||||
.padding(20)
|
||||
.align_self(Align::Center);
|
||||
let content = Scrollable::new(&mut self.scroll).spacing(20).padding(20);
|
||||
|
||||
//let content = (0..self.paragraph_count)
|
||||
// .fold(content, |column, _| column.push(lorem_ipsum()))
|
||||
|
|
@ -49,8 +44,12 @@ impl Application for Example {
|
|||
// .align_self(Align::Center),
|
||||
// );
|
||||
|
||||
(0..10)
|
||||
.fold(content, |content, _| {
|
||||
Column::new()
|
||||
.height(Length::Fill)
|
||||
.max_width(Length::Units(600))
|
||||
.align_self(Align::Center)
|
||||
.justify_content(Justify::Center)
|
||||
.push((0..3).fold(content, |content, _| {
|
||||
content.push(
|
||||
Image::new(format!(
|
||||
"{}/examples/resources/ferris.png",
|
||||
|
|
@ -59,7 +58,7 @@ impl Application for Example {
|
|||
.width(Length::Units(400))
|
||||
.align_self(Align::Center),
|
||||
)
|
||||
})
|
||||
}))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,12 +56,7 @@ where
|
|||
Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta_y, ..
|
||||
}) => {
|
||||
// TODO: Configurable speed (?)
|
||||
self.state.offset = (self.state.offset as i32
|
||||
- delta_y.round() as i32 * 15)
|
||||
.max(0)
|
||||
.min((content_bounds.height - bounds.height) as i32)
|
||||
as u32;
|
||||
self.state.scroll(delta_y, bounds, content_bounds);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -70,7 +65,8 @@ where
|
|||
let cursor_position = if is_mouse_over {
|
||||
Point::new(
|
||||
cursor_position.x,
|
||||
cursor_position.y + self.state.offset as f32,
|
||||
cursor_position.y
|
||||
+ self.state.offset(bounds, content_bounds) as f32,
|
||||
)
|
||||
} else {
|
||||
Point::new(cursor_position.x, -1.0)
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ impl scrollable::Renderer for Renderer {
|
|||
let content = layout.children().next().unwrap();
|
||||
let content_bounds = content.bounds();
|
||||
|
||||
let offset = scrollable.state.offset(bounds, content_bounds);
|
||||
|
||||
let cursor_position = if bounds.contains(cursor_position) {
|
||||
Point::new(
|
||||
cursor_position.x,
|
||||
cursor_position.y + scrollable.state.offset as f32,
|
||||
)
|
||||
Point::new(cursor_position.x, cursor_position.y + offset as f32)
|
||||
} else {
|
||||
Point::new(cursor_position.x, -1.0)
|
||||
};
|
||||
|
|
@ -30,7 +29,7 @@ impl scrollable::Renderer for Renderer {
|
|||
|
||||
let primitive = Primitive::Scrollable {
|
||||
bounds,
|
||||
offset: scrollable.state.offset,
|
||||
offset,
|
||||
content: Box::new(content),
|
||||
};
|
||||
|
||||
|
|
@ -41,7 +40,7 @@ impl scrollable::Renderer for Renderer {
|
|||
{
|
||||
let ratio = bounds.height / content_bounds.height;
|
||||
let scrollbar_height = bounds.height * ratio;
|
||||
let y_offset = scrollable.state.offset as f32 * ratio;
|
||||
let y_offset = offset as f32 * ratio;
|
||||
|
||||
let scrollbar = Primitive::Quad {
|
||||
bounds: Rectangle {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue