From 017d6a0dbfc369aa1ab64492150a9adcb75b8619 Mon Sep 17 00:00:00 2001 From: David Bliss Date: Thu, 11 Apr 2024 14:03:55 +0100 Subject: [PATCH] Add first preference --- src/app.rs | 18 +++++- src/app/components/preferences.rs | 94 ++++++++++++++++++++++++++----- 2 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/app.rs b/src/app.rs index 6b93f2eb..25dbf752 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,7 +32,7 @@ mod components; use self::components::{ about::AboutDialog, - preferences::PreferencesDialog, + preferences::{PreferencesDialog, PreferencesInput, PreferencesOutput}, album::{Album, AlbumFilter, AlbumInput, AlbumOutput}, folder_photos::{FolderPhotos, FolderPhotosInput, FolderPhotosOutput}, month_photos::{MonthPhotos, MonthPhotosInput, MonthPhotosOutput}, @@ -142,6 +142,9 @@ pub(super) enum AppMsg { // Cleanup events CleanupStarted, CleanupCompleted, + + // Preferences + PreferencesUpdated, } relm4::new_action_group!(pub(super) WindowActionGroup, "win"); @@ -320,6 +323,7 @@ impl SimpleComponent for App { set_icon_name: "image-alt-symbolic", }, + add_child = >k::Box { set_orientation: gtk::Orientation::Vertical, container_add: model.selfie_photos.widget(), @@ -485,7 +489,9 @@ impl SimpleComponent for App { let preferences_dialog = PreferencesDialog::builder() .launch(root.clone()) - .detach(); + .forward(sender.input_sender(), |msg| match msg { + PreferencesOutput::Updated => AppMsg::PreferencesUpdated, + }); let library_view_stack = adw::ViewStack::new(); @@ -553,7 +559,7 @@ impl SimpleComponent for App { let preferences_action = { let sender = model.preferences_dialog.sender().clone(); RelmAction::::new_stateless(move |_| { - sender.send(()).unwrap(); + sender.send(PreferencesInput::Present).unwrap(); }) }; @@ -711,6 +717,12 @@ impl SimpleComponent for App { self.banner.set_title("Database maintenance."); self.banner.set_revealed(true); } + + AppMsg::PreferencesUpdated => { + println!("Preferences updated."); + // TODO create a Preferences struct to hold preferences and send with update message. + self.show_selfies = AppWidgets::show_selfies(); + } } } diff --git a/src/app/components/preferences.rs b/src/app/components/preferences.rs index 334b6623..df7da486 100644 --- a/src/app/components/preferences.rs +++ b/src/app/components/preferences.rs @@ -4,38 +4,102 @@ use relm4::{adw, ComponentParts, ComponentSender, SimpleComponent}; use relm4::adw::prelude::AdwDialogExt; -use relm4::gtk::prelude::WidgetExt; +use relm4::gtk::prelude::SettingsExt; +use relm4::gtk::gio; +use relm4::adw::prelude::PreferencesDialogExt; +use relm4::adw::prelude::PreferencesPageExt; +use relm4::adw::prelude::PreferencesGroupExt; +use relm4::adw::prelude::ActionRowExt; +use relm4::adw::prelude::PreferencesRowExt; + +use crate::config::APP_ID; pub struct PreferencesDialog { parent: adw::ApplicationWindow, + dialog: adw::PreferencesDialog, + + // Preference values + show_selfies: bool, +} + +#[derive(Debug)] +pub enum PreferencesInput { + Present, + ShowSelfies(bool), } +#[derive(Debug)] +pub enum PreferencesOutput { + Updated, +} + +#[relm4::component(pub)] impl SimpleComponent for PreferencesDialog { type Init = adw::ApplicationWindow; - type Widgets = adw::PreferencesDialog; - type Input = (); - type Output = (); - type Root = adw::PreferencesDialog; - - fn init_root() -> Self::Root { - adw::PreferencesDialog::builder() - .build() + type Input = PreferencesInput; + type Output = PreferencesOutput; + + view!{ + adw::PreferencesDialog { + add = &adw::PreferencesPage { + add = &adw::PreferencesGroup { + set_title: "Views", + set_description: Some("Show or hide sidebar views"), + + adw::SwitchRow { + set_title: "Selfies", + set_subtitle: "Shows a separate view for selfies taken on iOS devices. Restart Fotema to apply.", + + #[watch] + set_active: model.show_selfies, + + connect_active_notify[sender] => move |switch| { + sender.input_sender().send(PreferencesInput::ShowSelfies(switch.is_active())).unwrap(); + }, + } + } + } + } } + fn init( parent: Self::Init, - root: Self::Root, - _sender: ComponentSender, + dialog: Self::Root, + sender: ComponentSender, ) -> ComponentParts { - let model = Self {parent}; - let widgets = root.clone(); + + let settings = gio::Settings::new(APP_ID); + let show_selfies = settings.boolean("show-selfies"); + + let model = Self { + parent, + dialog: dialog.clone(), + show_selfies, + }; + + let widgets = view_output!(); ComponentParts { model, widgets } } - fn update_view(&self, dialog: &mut Self::Widgets, _sender: ComponentSender) { - dialog.present(&self.parent); + fn update(&mut self, msg: Self::Input, sender: ComponentSender) { + match msg { + PreferencesInput::Present => { + let settings = gio::Settings::new(APP_ID); + self.show_selfies = settings.boolean("show-selfies"); + self.dialog.present(&self.parent); + }, + PreferencesInput::ShowSelfies(visible) => { + let settings = gio::Settings::new(APP_ID); + self.show_selfies = visible; + + settings.set_boolean("show-selfies", visible).expect("Update settings"); + + sender.output(PreferencesOutput::Updated).expect("Sending update prefs"); + }, + } } }