use druid::{BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx, Rect, Size, UpdateCtx, Widget, WidgetPod}; use druid::widget::Scroll; use crate::app::App; use crate::widget::notes_viewer::NotesViewer; pub struct NotesViewerScroll { scroll: WidgetPod>, } impl NotesViewerScroll { pub fn new() -> Self { Self { scroll: WidgetPod::new(Scroll::new(NotesViewer::new()).vertical()), } } } impl Widget for NotesViewerScroll { fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut App, env: &Env) { self.scroll.event(ctx, event, data, env); } fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &App, env: &Env) { self.scroll.lifecycle(ctx, event, data, env); } fn update(&mut self, ctx: &mut UpdateCtx, old_data: &App, data: &App, env: &Env) { self.scroll.update(ctx, data, env); let mut should_scroll = !old_data.notes_state.same(&data.notes_state) || (old_data.game_state.is_none() && data.game_state.is_some()); if let (Some(old), Some(new)) = (&old_data.notes_state, &data.notes_state) { if should_scroll && old.step_idx == new.step_idx && old.area_idx == new.area_idx { should_scroll = false; } } // scroll to new section if should_scroll { if let Some((step_idx, area_idx)) = data.notes_state .as_ref() .and_then(|state| state.step_idx.map(|step_idx| (step_idx, state.area_idx))) { let rect = self.scroll.widget().child().rect_for_step(step_idx, area_idx); println!("scroll to step {} area {}: {:?}", step_idx, area_idx, rect); if let Some(rect) = rect { let step_height = rect.height(); let scroll_size = self.scroll.layout_rect(); let mid_scroll = scroll_size.height() / 2.0; let mid_step = mid_scroll - (step_height / 2.0); let scroll_to = Rect::new(rect.x0, rect.y0, rect.x1, rect.y1 + mid_step); self.scroll.widget_mut().scroll_to(scroll_to); } } } } fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &App, env: &Env) -> Size { self.scroll.layout(ctx, bc, data, env) } fn paint(&mut self, ctx: &mut PaintCtx, data: &App, env: &Env) { self.scroll.paint(ctx, data, env); } }