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