From 58901dae372d6cfe53c29a2f124851cd5f82a723 Mon Sep 17 00:00:00 2001 From: Julian Mutter Date: Sat, 25 May 2024 22:01:42 +0200 Subject: [PATCH] Scroll to top on sheet listing changed (e.g. sorted) --- src/ui/app.rs | 22 +++++++++++++++------- src/ui/sheet_listing.rs | 24 ++++++++++++++++-------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index 1a3ebc1..bb7dc0f 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -5,6 +5,7 @@ use gtk::prelude::*; use log::debug; use relm4::{ component::{AsyncComponent, AsyncComponentParts}, + gtk::Adjustment, prelude::*, AsyncComponentSender, }; @@ -18,7 +19,7 @@ use crate::{ use super::{ mcdu::McduModel, - sheet_listing::{SheetListingInput, SheetListingModel}, + sheet_listing::{SheetListingInput, SheetListingModel, SheetListingOutput}, }; pub struct AppModel { @@ -27,6 +28,7 @@ pub struct AppModel { mcdu: Controller, sheets_listing: Controller, edit_mode: bool, + scroll_adjustment: Adjustment, } #[derive(Debug)] @@ -37,6 +39,7 @@ pub enum AppInput { Sort, Shuffle, SetEditMode(bool), + SheetListingContentsChanged, } pub struct AppInitData { @@ -94,6 +97,7 @@ impl AsyncComponent for AppModel { model.sheets_listing.widget(), set_vexpand: true, set_hexpand: true, + set_vadjustment: Some(&model.scroll_adjustment), }, }, model.mcdu.widget() { @@ -119,11 +123,13 @@ impl AsyncComponent for AppModel { let mut sheets = init_data.sheets; sheets.sort_by(|a, b| a.cmp(b).reverse()); - let sheets_listing = SheetListingModel::builder() - .launch(sheets) - .forward(sender.input_sender(), |response| { - AppInput::SheetPressed(response.sheet) - }); + let sheets_listing = SheetListingModel::builder().launch(sheets).forward( + sender.input_sender(), + |response| match response { + SheetListingOutput::SheetModelSelected(sheet) => AppInput::SheetPressed(sheet), + SheetListingOutput::ContentsChanged => AppInput::SheetListingContentsChanged, + }, + ); let model = AppModel { database: Arc::new(init_data.database), @@ -131,6 +137,7 @@ impl AsyncComponent for AppModel { mcdu, sheets_listing, edit_mode: false, + scroll_adjustment: Adjustment::builder().build(), }; let widgets = view_output!(); @@ -166,11 +173,12 @@ impl AsyncComponent for AppModel { let dir = Arc::clone(&self.directory); sender.oneshot_command(async move { sheet_validation::load_and_validate_sheets(&db, dir.as_ref()).await - }) + }); } AppInput::Sort => self.sheets_listing.emit(SheetListingInput::Sort), AppInput::Shuffle => self.sheets_listing.emit(SheetListingInput::Shuffle), AppInput::SetEditMode(edit_mode) => self.edit_mode = edit_mode, + AppInput::SheetListingContentsChanged => self.scroll_adjustment.set_value(0.0), } } diff --git a/src/ui/sheet_listing.rs b/src/ui/sheet_listing.rs index 0a7815e..b9a4b9a 100644 --- a/src/ui/sheet_listing.rs +++ b/src/ui/sheet_listing.rs @@ -24,15 +24,16 @@ pub enum SheetListingInput { } #[derive(Debug)] -pub struct SheetModelSelected { - pub sheet: Sheet, +pub enum SheetListingOutput { + SheetModelSelected(Sheet), + ContentsChanged, } #[relm4::component(pub)] impl SimpleComponent for SheetListingModel { type Init = Vec; type Input = SheetListingInput; - type Output = SheetModelSelected; + type Output = SheetListingOutput; view! { #[root] @@ -74,18 +75,25 @@ impl SimpleComponent for SheetListingModel { SheetListingInput::ListBoxRowClicked(index) => { let sheet_model = self.sheets.get(index as usize).unwrap(); sender - .output(SheetModelSelected { - sheet: sheet_model.sheet.clone(), - }) + .output(SheetListingOutput::SheetModelSelected( + sheet_model.sheet.clone(), + )) .unwrap(); } - SheetListingInput::Sort => sort_sheets(&mut self.sheets), - SheetListingInput::Shuffle => shuffle_sheets(&mut self.sheets), + SheetListingInput::Sort => { + sort_sheets(&mut self.sheets); + sender.output(SheetListingOutput::ContentsChanged); + } + SheetListingInput::Shuffle => { + shuffle_sheets(&mut self.sheets); + sender.output(SheetListingOutput::ContentsChanged); + } SheetListingInput::ReloadSheets(sheets) => { self.sheets.guard().clear(); for sheet_model_type in sheets { self.sheets.guard().push_back(sheet_model_type); } + sender.output(SheetListingOutput::ContentsChanged); } } }