67 lines
1.8 KiB
Rust
67 lines
1.8 KiB
Rust
use crate::prelude::*;
|
|
|
|
pub struct Scroll {
|
|
inner: WidgetId,
|
|
axis: Axis,
|
|
amt: f32,
|
|
snap_end: bool,
|
|
container_len: f32,
|
|
content_len: f32,
|
|
}
|
|
|
|
impl Widget for Scroll {
|
|
fn draw(&mut self, painter: &mut Painter) {
|
|
let output_len = painter.output_size().axis(self.axis);
|
|
let container_len = painter.region().axis(self.axis).len();
|
|
let content_len = painter
|
|
.len_axis(&self.inner, self.axis)
|
|
.apply_rest()
|
|
.within_len(container_len)
|
|
.to_abs(output_len);
|
|
self.container_len = container_len.to_abs(output_len);
|
|
self.content_len = content_len;
|
|
|
|
if self.snap_end {
|
|
self.amt = self.content_len - self.container_len;
|
|
}
|
|
self.update_amt();
|
|
|
|
let mut region = UiRegion::FULL.offset(Vec2::from_axis(self.axis, -self.amt, 0.0));
|
|
region.axis_mut(self.axis).end = region.axis(self.axis).start.offset(self.content_len);
|
|
painter.widget_within(&self.inner, region);
|
|
}
|
|
|
|
fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len {
|
|
ctx.width(&self.inner)
|
|
}
|
|
|
|
fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len {
|
|
ctx.height(&self.inner)
|
|
}
|
|
}
|
|
|
|
impl Scroll {
|
|
pub fn new(inner: WidgetId, axis: Axis) -> Self {
|
|
Self {
|
|
inner,
|
|
axis,
|
|
amt: 0.0,
|
|
snap_end: true,
|
|
container_len: 0.0,
|
|
content_len: 0.0,
|
|
}
|
|
}
|
|
|
|
pub fn update_amt(&mut self) {
|
|
self.amt = self.amt.max(0.0);
|
|
let len = (self.content_len - self.container_len).max(0.0);
|
|
self.amt = self.amt.min(len);
|
|
self.snap_end = self.amt == len;
|
|
}
|
|
|
|
pub fn scroll(&mut self, amt: f32) {
|
|
self.amt -= amt;
|
|
self.update_amt();
|
|
}
|
|
}
|