Skip to content

Commit e5d65f0

Browse files
committed
Use gio actions
1 parent 18ec2b6 commit e5d65f0

1 file changed

Lines changed: 107 additions & 95 deletions

File tree

src/window.rs

Lines changed: 107 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crate::tasks_button::TasksButton;
3030
use adw::prelude::*;
3131
use adw::subclass::prelude::*;
3232
use glib::{derived_properties, Properties};
33+
use gtk::gio::ActionEntry;
3334
use gtk::glib::clone;
3435
use gtk::{gdk, gio, glib, pango};
3536
use std::cell::RefCell;
@@ -76,42 +77,7 @@ mod imp {
7677

7778
fn class_init(klass: &mut Self::Class) {
7879
klass.bind_template();
79-
80-
klass.install_action("win.refresh", None, |win, _action, _target| {
81-
win.root_store().load_containers();
82-
});
8380
klass.add_binding_action(gdk::Key::F5, gdk::ModifierType::empty(), "win.refresh");
84-
85-
klass.install_action("win.upgrade-all", None, |win, _action, _target| {
86-
win.root_store().upgrade_all();
87-
});
88-
89-
klass.install_action("win.preferences", None, |win, _action, _target| {
90-
win.root_store()
91-
.set_current_dialog(TaggedObject::new("preferences"));
92-
});
93-
94-
klass.install_action("win.learn-more", None, |_win, _action, _target| {
95-
gtk::UriLauncher::new("https://distrobox.it").launch(
96-
None::<&gtk::Window>,
97-
None::<&gio::Cancellable>,
98-
|res| {
99-
if let Err(e) = res {
100-
tracing::error!(error = %e, "Failed to open Distrobox website");
101-
}
102-
},
103-
);
104-
});
105-
106-
klass.install_action("win.create-distrobox", None, |win, _action, _target| {
107-
win.root_store()
108-
.set_current_dialog(TaggedObject::new("create-distrobox"));
109-
});
110-
111-
klass.install_action("win.command-log", None, |win, _action, _target| {
112-
win.root_store()
113-
.set_current_dialog(TaggedObject::new("command-log"));
114-
});
11581
}
11682

11783
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
@@ -139,6 +105,7 @@ impl DistroShelfWindow {
139105
.property("root-store", root_store)
140106
.build();
141107

108+
this.setup_gactions();
142109
let this_clone = this.clone();
143110
this.root_store()
144111
.connect_selected_container_notify(move |root_store| {
@@ -183,9 +150,81 @@ impl DistroShelfWindow {
183150
});
184151
this.build_sidebar();
185152
this.root_store().load_containers();
153+
186154
this
187155
}
188156

157+
fn setup_gactions(&self) {
158+
let a = ActionEntry::builder;
159+
160+
let actions = [
161+
a("refresh")
162+
.activate(move |this: &DistroShelfWindow, _, _| {
163+
this.root_store().load_containers();
164+
}),
165+
a("upgrade-all")
166+
.activate(move |this: &DistroShelfWindow, _, _| {
167+
this.root_store().upgrade_all();
168+
}),
169+
a("preferences")
170+
.activate(|this, _, _| {
171+
this.root_store()
172+
.set_current_dialog(TaggedObject::new("preferences"));
173+
}),
174+
a("learn-more")
175+
.activate(|_, _, _| {
176+
gtk::UriLauncher::new("https://distrobox.it").launch(
177+
None::<&gtk::Window>,
178+
None::<&gio::Cancellable>,
179+
|res| {
180+
if let Err(e) = res {
181+
tracing::error!(error = %e, "Failed to open Distrobox website");
182+
}
183+
},
184+
);
185+
}),
186+
a("create-distrobox")
187+
.activate(|this, _, _| {
188+
this.root_store()
189+
.set_current_dialog(TaggedObject::new("create-distrobox"));
190+
}),
191+
a("command-log")
192+
.activate(|this, _, _| {
193+
this.root_store()
194+
.set_current_dialog(TaggedObject::new("command-log"));
195+
}),
196+
a("clone-container")
197+
.activate(|this, _, _| {
198+
this.build_clone_dialog();
199+
}),
200+
a("upgrade-container")
201+
.activate(|this, _, _| {
202+
let task = this.root_store().selected_container().unwrap().upgrade();
203+
this.root_store().view_task(&task);
204+
}),
205+
a("view-exportable-apps")
206+
.activate(|this, _, _| {
207+
this.root_store().view_exportable_apps();
208+
}),
209+
a("install-package")
210+
.activate(|this, _, _| {
211+
this.build_install_package_dialog();
212+
}),
213+
a("stop-container")
214+
.activate(|this, _, _| {
215+
this.root_store().selected_container().unwrap().stop();
216+
}),
217+
a("delete-container")
218+
.activate(|this, _, _| {
219+
this.build_delete_dialog();
220+
}),
221+
a("open-terminal")
222+
.activate(|this, _, _| {
223+
this.open_terminal();
224+
}),
225+
];
226+
self.add_action_entries(actions.into_iter().map(|entry| entry.build()));
227+
}
189228
fn build_sidebar(&self) {
190229
let imp = self.imp();
191230

@@ -314,43 +353,12 @@ impl DistroShelfWindow {
314353

315354
let stop_btn = gtk::Button::from_icon_name("media-playback-stop-symbolic");
316355
stop_btn.set_tooltip_text(Some("Stop"));
317-
stop_btn.connect_clicked(clone!(
318-
#[weak(rename_to=this)]
319-
self,
320-
move |_| {
321-
this.root_store().selected_container().unwrap().stop();
322-
}
323-
));
356+
stop_btn.set_action_name(Some("win.stop-container"));
324357
status_child.append(&stop_btn);
325358

326359
let terminal_btn = gtk::Button::from_icon_name("terminal-symbolic");
327360
terminal_btn.set_tooltip_text(Some("Open Terminal"));
328-
terminal_btn.connect_clicked(clone!(
329-
#[weak(rename_to = this)]
330-
self,
331-
move |_| {
332-
let task = this
333-
.root_store()
334-
.selected_container()
335-
.unwrap()
336-
.spawn_terminal();
337-
task.connect_status_notify(move |task| {
338-
if let Some(_) = &*task.error() {
339-
let toast = adw::Toast::new("Check your terminal settings.");
340-
toast.set_button_label(Some("Preferences"));
341-
toast.connect_button_clicked(clone!(
342-
#[weak]
343-
this,
344-
move |_| {
345-
this.root_store()
346-
.set_current_dialog(TaggedObject::new("preferences"));
347-
}
348-
));
349-
this.add_toast(toast);
350-
}
351-
});
352-
}
353-
));
361+
terminal_btn.set_action_name(Some("win.open-terminal"));
354362
status_child.append(&terminal_btn);
355363

356364
status_row.add_suffix(&status_child);
@@ -373,20 +381,15 @@ impl DistroShelfWindow {
373381
"Upgrade Container",
374382
"software-update-available-symbolic",
375383
"Update all packages",
376-
|win| {
377-
let task = win.root_store().selected_container().unwrap().upgrade();
378-
win.root_store().view_task(&task);
379-
},
384+
"win.upgrade-container",
380385
);
381386
actions_group.add(&upgrade_row);
382387

383388
let apps_row = self.create_button_row(
384389
"Applications",
385390
"view-list-bullet-symbolic",
386391
"Manage exportable applications",
387-
|win| {
388-
win.root_store().view_exportable_apps();
389-
},
392+
"win.view-exportable-apps",
390393
);
391394
actions_group.add(&apps_row);
392395

@@ -396,9 +399,7 @@ impl DistroShelfWindow {
396399
&format!("Install {} Package", installable_file),
397400
"package-symbolic",
398401
"Install packages into container",
399-
|win| {
400-
win.build_install_package_dialog();
401-
},
402+
"win.install-package",
402403
);
403404
actions_group.add(&install_package_row);
404405
}
@@ -408,9 +409,7 @@ impl DistroShelfWindow {
408409
"Clone Container",
409410
"edit-copy-symbolic",
410411
"Create a copy of this container",
411-
|win| {
412-
win.build_clone_dialog();
413-
},
412+
"win.clone-container",
414413
);
415414
actions_group.add(&clone_row);
416415

@@ -423,9 +422,7 @@ impl DistroShelfWindow {
423422
"Delete Container",
424423
"user-trash-symbolic",
425424
"Permanently remove this container and all its data",
426-
|win| {
427-
win.build_delete_dialog();
428-
},
425+
"win.delete-container",
429426
);
430427
delete_row.add_css_class("error");
431428

@@ -445,6 +442,30 @@ impl DistroShelfWindow {
445442
self.imp().main_slot.set_child(Some(&widget));
446443
}
447444

445+
fn open_terminal(&self) {
446+
let task = self
447+
.root_store()
448+
.selected_container()
449+
.unwrap()
450+
.spawn_terminal();
451+
let this = self.clone();
452+
task.connect_status_notify(move |task| {
453+
if let Some(_) = &*task.error() {
454+
let toast = adw::Toast::new("Check your terminal settings.");
455+
toast.set_button_label(Some("Preferences"));
456+
toast.connect_button_clicked(clone!(
457+
#[weak]
458+
this,
459+
move |_| {
460+
this.root_store()
461+
.set_current_dialog(TaggedObject::new("preferences"));
462+
}
463+
));
464+
this.add_toast(toast);
465+
}
466+
});
467+
}
468+
448469
fn build_delete_dialog(&self) {
449470
let dialog = adw::AlertDialog::builder()
450471
.heading("Delete this container?")
@@ -769,25 +790,16 @@ impl DistroShelfWindow {
769790
title: &str,
770791
icon_name: &str,
771792
subtitle: &str,
772-
action_fn: impl Fn(&Self) + 'static,
793+
action_name: &str,
773794
) -> adw::ActionRow {
774795
let row = adw::ActionRow::new();
775796
row.set_title(title);
776797
row.set_subtitle(subtitle);
777798

778799
let icon = gtk::Image::from_icon_name(icon_name);
779800
row.add_prefix(&icon);
780-
781801
row.set_activatable(true);
782-
783-
row.connect_activated(clone!(
784-
#[weak(rename_to = this)]
785-
self,
786-
move |_| {
787-
action_fn(&this);
788-
}
789-
));
790-
802+
row.set_action_name(Some(action_name));
791803
row
792804
}
793805
}

0 commit comments

Comments
 (0)