linebender / druid

A data-first Rust-native UI design toolkit.
https://linebender.org/druid/
Apache License 2.0
9.57k stars 566 forks source link

Scroll to bottom on dynamic content #2404

Closed insertokname closed 4 months ago

insertokname commented 4 months ago

General description

I want to be able to automatically scroll to the bottom of a a Scroll whenever content is changed.

Here is a simplified version of my setup: I have a button that modifies the state of AppState::log (appends text or any operation that modifies it) I have a Scroll<AppState, Label<AppState>>

I want the scroll to automatically go to the bottom of the content whenever it is updated.

i have also seen something similar in #2034 but it seems that it has the same issue as my implementation.

My attempts at solving this

I made a custom controller that looks like this:

struct ScrollController;

impl<W: Widget<AppState>> druid::widget::Controller<AppState, Scroll<AppState, W>>
    for ScrollController
{
    fn update(
        &mut self,
        child: &mut Scroll<AppState, W>,
        ctx: &mut druid::UpdateCtx,
        old_data: &AppState,
        data: &AppState,
        env: &Env,
    ) {
        if old_data.log != data.log{
                child.scroll_by(ctx, (f64::INFINITY, f64::INFINITY).into());
        }

        child.update(ctx, old_data, data, env);
    }
}

This partially works and only goes to the somewhere near bottom of the text that was written before the last log.

I am not quite sure why this is but any help on this would be greatly appreciated!

insertokname commented 4 months ago

managed to do some workarounds specific to my usecase...