Expose scrollable offset properly

This commit is contained in:
Héctor Ramón Jiménez 2019-10-27 01:24:08 +02:00
parent 719c073fc6
commit 09bd2c46c0
4 changed files with 44 additions and 26 deletions

View file

@ -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)
}
}

View file

@ -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()
}
}

View file

@ -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)

View file

@ -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 {