ffxii-tza-auto-notes/src/widget/notes_viewer_scroll.rs

68 lines
2.5 KiB
Rust
Executable File

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<App, Scroll<App, NotesViewer>>,
}
impl NotesViewerScroll {
pub fn new() -> Self {
Self {
scroll: WidgetPod::new(Scroll::new(NotesViewer::new()).vertical()),
}
}
}
impl Widget<App> 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);
}
}