feat: switch to relm4 component macro
This commit is contained in:
parent
fb227660bb
commit
89390e4f3f
1 changed files with 66 additions and 92 deletions
158
src/main.rs
158
src/main.rs
|
@ -10,7 +10,7 @@ use relm::{Dialog, DialogInput};
|
|||
use relm4::{
|
||||
Component, ComponentController, Controller, RelmApp,
|
||||
adw::{self, prelude::*},
|
||||
gtk::{self, gio, glib::clone},
|
||||
gtk::{self, gio},
|
||||
prelude::{AsyncComponent, AsyncComponentParts},
|
||||
tokio,
|
||||
};
|
||||
|
@ -47,11 +47,6 @@ enum Message {
|
|||
Nothing,
|
||||
}
|
||||
|
||||
struct Widgets {
|
||||
file_picker_row: adw::ActionRow,
|
||||
send_button: gtk::Button,
|
||||
}
|
||||
|
||||
struct Tyrolienne {
|
||||
config: Config,
|
||||
video_path: Option<PathBuf>,
|
||||
|
@ -68,19 +63,69 @@ impl Tyrolienne {
|
|||
}
|
||||
}
|
||||
|
||||
#[relm4::component(async)]
|
||||
impl AsyncComponent for Tyrolienne {
|
||||
type Input = Message;
|
||||
type Output = ();
|
||||
type CommandOutput = ();
|
||||
type Init = Config;
|
||||
type Root = adw::ApplicationWindow;
|
||||
type Widgets = Widgets;
|
||||
|
||||
fn init_root() -> Self::Root {
|
||||
adw::ApplicationWindow::builder()
|
||||
.title("Tyrolienne")
|
||||
.default_width(500)
|
||||
.build()
|
||||
view! {
|
||||
adw::ApplicationWindow {
|
||||
set_title: Some("Tyrolienne"),
|
||||
set_default_width: 500,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 0,
|
||||
|
||||
adw::HeaderBar {},
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 32,
|
||||
set_margin_top: 32,
|
||||
set_margin_bottom: 32,
|
||||
set_margin_start: 32,
|
||||
set_margin_end: 32,
|
||||
|
||||
gtk::ListBox {
|
||||
set_selection_mode: gtk::SelectionMode::None,
|
||||
set_css_classes: &["boxed-list"],
|
||||
|
||||
adw::ActionRow {
|
||||
set_activatable: true,
|
||||
set_css_classes: &["property"],
|
||||
set_title: "Video file",
|
||||
#[watch]
|
||||
set_subtitle: &model.display_video_path(),
|
||||
connect_activated => Message::OpenFilePicker,
|
||||
},
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: "Folder",
|
||||
set_model: Some(&folder_store),
|
||||
set_expression: Some(&folder_expression),
|
||||
connect_activated[sender] => move |r| {
|
||||
if let Some(item) = r
|
||||
.selected_item()
|
||||
.and_then(|i| i.downcast::<GtkZiplineFolder>().ok())
|
||||
{
|
||||
sender.input(Message::SetFolder(item.as_folder()));
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label: "Send",
|
||||
#[watch]
|
||||
set_sensitive: model.video_path.is_some(),
|
||||
connect_clicked => Message::StartTheProcess,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
|
@ -110,85 +155,22 @@ impl AsyncComponent for Tyrolienne {
|
|||
}
|
||||
};
|
||||
|
||||
let file_picker_row = adw::ActionRow::builder()
|
||||
.activatable(true)
|
||||
.title("Video file")
|
||||
.subtitle(model.display_video_path())
|
||||
.css_classes(["property"])
|
||||
.build();
|
||||
file_picker_row.connect_activated(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
move |_| sender.input(Message::OpenFilePicker)
|
||||
));
|
||||
|
||||
let mut gtk_folders = folders
|
||||
.iter()
|
||||
.map(GtkZiplineFolder::from_folder)
|
||||
.collect::<Vec<_>>();
|
||||
gtk_folders.insert(0, GtkZiplineFolder::none());
|
||||
|
||||
let store = gio::ListStore::new::<GtkZiplineFolder>();
|
||||
store.extend_from_slice(>k_folders);
|
||||
let folder_store = gio::ListStore::new::<GtkZiplineFolder>();
|
||||
folder_store.extend_from_slice(>k_folders);
|
||||
|
||||
let folder_row = adw::ComboRow::builder()
|
||||
.title("Folder")
|
||||
.model(&store)
|
||||
.expression(gtk::PropertyExpression::new(
|
||||
GtkZiplineFolder::r#type(),
|
||||
None::<>k::Expression>,
|
||||
"name",
|
||||
))
|
||||
.build();
|
||||
folder_row.connect_activated(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
move |r| {
|
||||
if let Some(item) = r
|
||||
.selected_item()
|
||||
.and_then(|i| i.downcast::<GtkZiplineFolder>().ok())
|
||||
{
|
||||
sender.input(Message::SetFolder(item.as_folder()));
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
let send_button = gtk::Button::builder()
|
||||
.label("Send")
|
||||
.sensitive(false)
|
||||
.margin_start(32)
|
||||
.margin_end(32)
|
||||
.margin_bottom(32)
|
||||
.build();
|
||||
send_button.connect_clicked(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
move |_| sender.input(Message::StartTheProcess)
|
||||
));
|
||||
|
||||
let list = gtk::ListBox::builder()
|
||||
.margin_top(32)
|
||||
.margin_end(32)
|
||||
.margin_bottom(32)
|
||||
.margin_start(32)
|
||||
.selection_mode(gtk::SelectionMode::None)
|
||||
.css_classes(["boxed-list"])
|
||||
.build();
|
||||
list.append(&file_picker_row);
|
||||
list.append(&folder_row);
|
||||
|
||||
let root_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
||||
root_box.append(&adw::HeaderBar::new());
|
||||
root_box.append(&list);
|
||||
root_box.append(&send_button);
|
||||
|
||||
root.set_content(Some(&root_box));
|
||||
|
||||
let widgets = Widgets {
|
||||
file_picker_row,
|
||||
send_button,
|
||||
};
|
||||
let folder_expression = gtk::PropertyExpression::new(
|
||||
GtkZiplineFolder::r#type(),
|
||||
None::<>k::Expression>,
|
||||
"name",
|
||||
);
|
||||
|
||||
let widgets = view_output!();
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
|
@ -222,14 +204,6 @@ impl AsyncComponent for Tyrolienne {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_view(&self, widgets: &mut Self::Widgets, _sender: relm4::AsyncComponentSender<Self>) {
|
||||
widgets
|
||||
.file_picker_row
|
||||
.set_subtitle(&self.display_video_path());
|
||||
|
||||
widgets.send_button.set_sensitive(self.video_path.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue