add reload request option on cancel

This commit is contained in:
yggverse 2024-12-07 09:35:26 +02:00
parent cf4261cac2
commit d93c111cbd
6 changed files with 58 additions and 13 deletions

View File

@ -23,6 +23,15 @@ impl Gemini {
let widget = Rc::new(Widget::new(profile.clone(), &auth_url)); let widget = Rc::new(Widget::new(profile.clone(), &auth_url));
// Init events // Init events
widget.on_cancel({
let action = action.clone();
move |is_reload_request| {
if is_reload_request {
action.reload.activate();
}
}
});
widget.on_apply({ widget.on_apply({
let widget = widget.clone(); let widget = widget.clone();
move |response| { move |response| {

View File

@ -10,7 +10,7 @@ use adw::{
AlertDialog, ResponseAppearance, AlertDialog, ResponseAppearance,
}; };
use gtk::prelude::IsA; use gtk::prelude::IsA;
use std::rc::Rc; use std::{cell::Cell, rc::Rc};
// Defaults // Defaults
const HEADING: &str = "Ident"; const HEADING: &str = "Ident";
@ -27,6 +27,7 @@ pub struct Widget {
// pub action: Rc<Action>, // pub action: Rc<Action>,
pub form: Rc<Form>, pub form: Rc<Form>,
pub alert_dialog: AlertDialog, pub alert_dialog: AlertDialog,
pub is_reload_request: Rc<Cell<bool>>,
} }
impl Widget { impl Widget {
@ -37,6 +38,9 @@ impl Widget {
// Init actions // Init actions
let action = Rc::new(Action::new()); let action = Rc::new(Action::new());
// Page may require reload for some widget actions
let is_reload_request = Rc::new(Cell::new(false));
// Init child container // Init child container
let form = Rc::new(Form::new(profile, action.clone(), auth_url)); let form = Rc::new(Form::new(profile, action.clone(), auth_url));
@ -67,7 +71,11 @@ impl Widget {
action.update.connect_activate({ action.update.connect_activate({
let form = form.clone(); let form = form.clone();
let alert_dialog = alert_dialog.clone(); let alert_dialog = alert_dialog.clone();
move || { let is_reload_request = is_reload_request.clone();
move |_is_reload_request| {
// Update reload state
is_reload_request.replace(_is_reload_request);
// Update child components // Update child components
form.update(); form.update();
@ -81,13 +89,14 @@ impl Widget {
// action, // action,
form, form,
alert_dialog, alert_dialog,
is_reload_request,
} }
} }
// Actions // Actions
/// Callback wrapper for `apply` [response](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/signal.AlertDialog.response.html) /// Callback wrapper to apply
/// * return `Value` enum or new record request on `None` /// [response](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/signal.AlertDialog.response.html)
pub fn on_apply(&self, callback: impl Fn(Value) + 'static) { pub fn on_apply(&self, callback: impl Fn(Value) + 'static) {
self.alert_dialog.connect_response(Some(RESPONSE_APPLY.0), { self.alert_dialog.connect_response(Some(RESPONSE_APPLY.0), {
let form = self.form.clone(); let form = self.form.clone();
@ -101,6 +110,23 @@ impl Widget {
}); });
} }
/// Callback wrapper to cancel
/// [response](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/signal.AlertDialog.response.html)
/// * return require reload state
pub fn on_cancel(&self, callback: impl Fn(bool) + 'static) {
self.alert_dialog
.connect_response(Some(RESPONSE_CANCEL.0), {
let is_reload_request = self.is_reload_request.take();
move |this, response| {
// Prevent double-click action
this.set_response_enabled(response, false);
// Result
callback(is_reload_request)
}
});
}
/// Show dialog with new preset /// Show dialog with new preset
pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) { pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) {
self.form.update(); self.form.update();

View File

@ -1,4 +1,8 @@
use gtk::{gio::SimpleAction, glib::uuid_string_random, prelude::ActionExt}; use gtk::{
gio::SimpleAction,
glib::uuid_string_random,
prelude::{ActionExt, StaticVariantType, ToVariant},
};
/// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `Update` action /// [SimpleAction](https://docs.gtk.org/gio/class.SimpleAction.html) wrapper for `Update` action
pub struct Update { pub struct Update {
@ -11,7 +15,7 @@ impl Update {
/// Create new `Self` /// Create new `Self`
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
gobject: SimpleAction::new(&uuid_string_random(), None), gobject: SimpleAction::new(&uuid_string_random(), Some(&bool::static_variant_type())),
} }
} }
@ -19,15 +23,21 @@ impl Update {
/// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal /// Emit [activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
/// with formatted for this action [Variant](https://docs.gtk.org/glib/struct.Variant.html) value /// with formatted for this action [Variant](https://docs.gtk.org/glib/struct.Variant.html) value
pub fn activate(&self) { pub fn activate(&self, is_reload_request: bool) {
self.gobject.activate(None); self.gobject.activate(Some(&is_reload_request.to_variant()));
} }
// Events // Events
/// Define callback function for /// Define callback function for
/// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal /// [SimpleAction::activate](https://docs.gtk.org/gio/signal.SimpleAction.activate.html) signal
pub fn connect_activate(&self, callback: impl Fn() + 'static) { pub fn connect_activate(&self, callback: impl Fn(bool) + 'static) {
self.gobject.connect_activate(move |_, _| callback()); self.gobject.connect_activate(move |_, this| {
callback(
this.expect("Expected `is_reload_request` variant")
.get::<bool>()
.expect("Parameter type does not match `bool` type"),
)
});
} }
} }

View File

@ -89,7 +89,7 @@ impl File {
} }
} }
button.set_sensitive(true); // unlock button.set_sensitive(true); // unlock
action_widget.update.activate() action_widget.update.activate(true)
} }
}); });
} }

View File

@ -134,7 +134,7 @@ impl List {
.build(); .build();
// Connect events // Connect events
dropdown.connect_selected_notify(move |_| action_widget.update.activate()); dropdown.connect_selected_notify(move |_| action_widget.update.activate(false));
// Return activated `Self` // Return activated `Self`
Self { Self {

View File

@ -29,7 +29,7 @@ impl Name {
.build(); .build();
// Init events // Init events
entry.connect_changed(move |_| action_widget.update.activate()); entry.connect_changed(move |_| action_widget.update.activate(false));
// Return activated `Self` // Return activated `Self`
Self { entry } Self { entry }