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:
| M | src/app.rs | | | 79 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
| M | src/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!();