heic2jpg

git clone git://archive.git.mtrnord.blog/MTRNord/heic2jpg.git
Log | Files | Refs | README | LICENSE

commit 0047eb9494f60479a0b16bd0c80fe2ad56c43253
parent 8b71840cb89291cda89ef13defa8239e4eb2f2d3
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 10 Nov 2024 00:50:45 +0100

Setup output folder selection and prepare conversion

Diffstat:
Msrc/app.rs | 79++++++++++++++++++++++++++++++++++++-------------------------------------------
Msrc/select_folder.rs | 46+++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 77 insertions(+), 48 deletions(-)

diff --git a/src/app.rs b/src/app.rs @@ -1,6 +1,6 @@ use crate::config::{APP_ID, PROFILE}; use crate::modals::about::AboutDialog; -use crate::select_folder::{SelectFolder, SelectFolderOut}; +use crate::select_folder::{InOut, SelectFolder, SelectFolderOut}; use gtk::prelude::*; use gtk::{gio, glib}; use relm4::{ @@ -25,6 +25,7 @@ pub(super) enum AppMsg { DeselectInputFolder, DeselectOutputFolder, Quit, + Noop, } relm4::new_action_group!(pub(super) WindowActionGroup, "win"); @@ -90,50 +91,40 @@ impl SimpleComponent for App { }, // If no folder is selected, show the folder selector - if model.input_folder.is_none() { - gtk::Box { - set_vexpand: true, - set_hexpand: true, - append = model.input_folder_selector.widget(), - } - } else { + if model.input_folder.is_some() && model.output_folder.is_some() { adw::StatusPage { set_hexpand: true, set_vexpand: true, - set_title: "Select Output Folder", - set_description: Some("Select the folder where the converted JPG files should be saved"), + set_title: "Start Conversion", + set_description: Some("Press the button to start the conversion"), gtk::Box { - set_orientation: gtk::Orientation::Vertical, + set_halign: gtk::Align::Center, + set_orientation: gtk::Orientation::Horizontal, set_spacing: 24, - gtk::Label { - set_halign: gtk::Align::Center, - #[watch] - set_text: &format!("Selected Input Folder: {}", model.input_folder.as_ref().map(|p| p.to_string_lossy()).unwrap_or_default()) - }, - gtk::Box { - set_halign: gtk::Align::Center, - set_orientation: gtk::Orientation::Horizontal, - set_spacing: 24, - gtk::Button { - set_halign: gtk::Align::Center, - set_label: "Select output directory", - connect_clicked[sender] => move |_| { - - } - }, - - gtk::Button { - set_halign: gtk::Align::Center, - set_label: "Abort", - connect_clicked[sender] => move |_| { - sender.input(AppMsg::DeselectInputFolder); - } - }, + gtk::Button { + set_label: "Convert", + connect_clicked[sender] => move |_| { + // TODO: Implement conversion using worker and imagick + sender.input(AppMsg::Quit); + } } } } + } else if model.input_folder.is_none() { + gtk::Box { + set_vexpand: true, + set_hexpand: true, + append = model.input_folder_selector.widget(), + } + } else { + gtk::Box { + set_vexpand: true, + set_hexpand: true, + append = model.output_folder_selector.widget(), + } } + } } @@ -150,17 +141,18 @@ impl SimpleComponent for App { .detach(); let input_folder_selector = SelectFolder::builder() - .launch(()) + .launch(InOut::Input) .forward(sender.input_sender(), |msg| match msg { SelectFolderOut::FolderSelected(path) => AppMsg::InputFolderSelected(path), + SelectFolderOut::AbortLast => AppMsg::Noop, + }); + let output_folder_selector = + SelectFolder::builder() + .launch(InOut::Output) + .forward(sender.input_sender(), |msg| match msg { + SelectFolderOut::FolderSelected(path) => AppMsg::OutputFolderSelected(path), + SelectFolderOut::AbortLast => AppMsg::DeselectInputFolder, }); - let output_folder_selector = - SelectFolder::builder() - .launch(()) - .forward(sender.input_sender(), |msg| match msg { - SelectFolderOut::FolderSelected(path) => AppMsg::InputFolderSelected(path), - }); - let model = Self { about_dialog, @@ -204,6 +196,7 @@ impl SimpleComponent for App { AppMsg::OutputFolderSelected(path) => self.output_folder = Some(path), AppMsg::DeselectOutputFolder => self.output_folder = None, AppMsg::Quit => main_application().quit(), + AppMsg::Noop => {} } } diff --git a/src/select_folder.rs b/src/select_folder.rs @@ -6,9 +6,19 @@ use relm4::{ use relm4_components::{open_dialog::*, save_dialog::*}; use std::path::PathBuf; +#[derive(Debug, PartialEq)] +pub(super) enum InOut { + Input, + Output, +} + +#[derive(Debug)] pub(super) struct SelectFolder { open_dialog: Controller<OpenDialog>, folder: Option<PathBuf>, + description: String, + button_label: String, + direction: InOut, } #[derive(Debug)] @@ -21,11 +31,12 @@ pub(super) enum SelectFolderMsg { #[derive(Debug)] pub(super) enum SelectFolderOut { FolderSelected(PathBuf), + AbortLast, } #[relm4::component(pub)] impl SimpleComponent for SelectFolder { - type Init = (); + type Init = InOut; type Input = SelectFolderMsg; type Output = SelectFolderOut; @@ -34,28 +45,50 @@ impl SimpleComponent for SelectFolder { set_hexpand: true, set_vexpand: true, set_title: "Select Folder", - set_description: Some("Select the folder containing the HEIC files you want to convert"), + set_description: Some(&model.description), gtk::Box { - set_orientation: gtk::Orientation::Vertical, + set_halign: gtk::Align::Center, + set_orientation: gtk::Orientation::Horizontal, set_spacing: 24, gtk::Button { set_halign: gtk::Align::Center, - set_label: "Select input directory", + set_label: &model.button_label, connect_clicked[sender] => move |_| { sender.input(SelectFolderMsg::OpenRequest); } }, + + // If this is the output folder selector, add an Abort button + gtk::Button { + set_visible: model.direction == InOut::Output, + set_halign: gtk::Align::Center, + set_label: "Abort", + connect_clicked[sender] => move |_| { + let _ = sender.output(SelectFolderOut::AbortLast); + } + } } } } fn init( - _init: Self::Init, + init: Self::Init, root: Self::Root, sender: ComponentSender<Self>, ) -> ComponentParts<Self> { + let (description, button_label) = match init { + InOut::Input => ( + "Select the folder where the Heic files can be found", + "Select input directory", + ), + InOut::Output => ( + "Select the folder where the JPG files are meant to be saved", + "Select output directory", + ), + }; + let dialog_settings = OpenDialogSettings { folder_mode: true, ..Default::default() @@ -72,6 +105,9 @@ impl SimpleComponent for SelectFolder { let model = Self { open_dialog, folder: None, + description: description.to_string(), + button_label: button_label.to_string(), + direction: init, }; let widgets = view_output!();