use gtk::prelude::{DialogExt, GtkWindowExt, WidgetExt};
use relm4::{gtk, ComponentParts, ComponentSender, SimpleComponent};
#[derive(Debug)]
pub struct AlertSettings {
pub text: String,
pub secondary_text: Option<String>,
pub is_modal: bool,
pub destructive_accept: bool,
pub confirm_label: String,
pub cancel_label: String,
pub option_label: Option<String>,
}
#[derive(Debug)]
pub struct Alert {
settings: AlertSettings,
is_active: bool,
}
#[derive(Debug)]
pub enum AlertMsg {
Show,
#[doc(hidden)]
Response(gtk::ResponseType),
}
#[derive(Debug)]
pub enum AlertResponse {
Confirm,
Cancel,
Option,
}
#[relm4::component(pub)]
impl SimpleComponent for Alert {
type Init = AlertSettings;
type Input = AlertMsg;
type Output = AlertResponse;
view! {
#[name(dialog)]
gtk::MessageDialog {
set_message_type: gtk::MessageType::Question,
#[watch]
set_visible: model.is_active,
connect_response[sender] => move |_, response| {
sender.input(AlertMsg::Response(response));
},
set_text: Some(&model.settings.text),
set_secondary_text: model.settings.secondary_text.as_deref(),
set_modal: model.settings.is_modal,
add_button: (&model.settings.confirm_label, gtk::ResponseType::Accept),
add_button: (&model.settings.cancel_label, gtk::ResponseType::Cancel),
}
}
fn init(
settings: AlertSettings,
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = Alert {
settings,
is_active: false,
};
let widgets = view_output!();
if let Some(option_label) = &model.settings.option_label {
widgets
.dialog
.add_button(option_label, gtk::ResponseType::Other(0));
}
if model.settings.destructive_accept {
let accept_widget = widgets
.dialog
.widget_for_response(gtk::ResponseType::Accept)
.expect("No button for accept response set");
accept_widget.add_css_class("destructive-action");
}
ComponentParts { model, widgets }
}
fn update(&mut self, input: AlertMsg, sender: ComponentSender<Self>) {
match input {
AlertMsg::Show => {
self.is_active = true;
}
AlertMsg::Response(ty) => {
self.is_active = false;
sender
.output(match ty {
gtk::ResponseType::Accept => AlertResponse::Confirm,
gtk::ResponseType::Other(_) => AlertResponse::Option,
_ => AlertResponse::Cancel,
})
.unwrap();
}
}
}
}