transient_dialog/
transient_dialog.rs1#![allow(deprecated)]
4
5use std::convert::identity;
6
7use gtk::glib;
8use gtk::prelude::{ButtonExt, GtkWindowExt, WidgetExt};
9use relm4::MessageBroker;
10use relm4::{
11 Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp,
12 SimpleComponent,
13};
14
15static DIALOG_BROKER: MessageBroker<DialogMsg> = MessageBroker::new();
16
17struct Dialog {
18 visible: bool,
19}
20
21#[derive(Debug)]
22enum DialogMsg {
23 Show,
24 Hide,
25}
26
27#[relm4::component]
28impl SimpleComponent for Dialog {
29 type Init = ();
30 type Input = DialogMsg;
31 type Output = ButtonMsg;
32
33 view! {
34 dialog = gtk::Dialog {
35 #[watch]
36 set_visible: model.visible,
37 set_modal: true,
38
39 #[wrap(Some)]
40 set_child = >k::Label {
41 set_width_request: 200,
42 set_height_request: 80,
43 set_halign: gtk::Align::Center,
44 set_valign: gtk::Align::Center,
45 #[watch]
46 set_label: if dialog.transient_for().is_some() {
47 "I'm transient!"
48 } else {
49 "I'm not transient..."
50 },
51 },
52
53 connect_close_request[sender] => move |_| {
54 sender.input(DialogMsg::Hide);
55 glib::Propagation::Stop
56 }
57 }
58 }
59
60 fn init(
61 _init: Self::Init,
62 root: Self::Root,
63 sender: ComponentSender<Self>,
64 ) -> ComponentParts<Self> {
65 let model = Dialog { visible: false };
66 let widgets = view_output!();
67 ComponentParts { model, widgets }
68 }
69
70 fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
71 match msg {
72 DialogMsg::Show => self.visible = true,
73 DialogMsg::Hide => self.visible = false,
74 }
75 }
76}
77
78struct Button {
79 #[allow(dead_code)]
80 dialog: Controller<Dialog>,
81}
82
83#[derive(Debug)]
84enum ButtonMsg {}
85
86#[relm4::component]
87impl SimpleComponent for Button {
88 type Init = ();
89 type Input = ButtonMsg;
90 type Output = AppMsg;
91
92 view! {
93 button = >k::Button {
94 set_label: "Show the dialog",
95 connect_clicked => move |_| {
96 DIALOG_BROKER.send(DialogMsg::Show);
97 }
98 }
99 }
100
101 fn init(
102 _init: Self::Init,
103 root: Self::Root,
104 sender: ComponentSender<Self>,
105 ) -> ComponentParts<Self> {
106 let dialog = Dialog::builder()
111 .transient_for(&root)
112 .launch_with_broker((), &DIALOG_BROKER)
113 .forward(sender.input_sender(), identity);
114
115 let model = Button { dialog };
116 let widgets = view_output!();
117 ComponentParts { model, widgets }
118 }
119
120 fn update(&mut self, _msg: Self::Input, _sender: ComponentSender<Self>) {}
121}
122
123#[derive(Debug)]
124enum AppMsg {}
125
126struct App {
127 button: Controller<Button>,
128}
129
130#[relm4::component]
131impl SimpleComponent for App {
132 type Init = ();
133 type Input = AppMsg;
134 type Output = ();
135
136 view! {
137 main_window = gtk::ApplicationWindow {
138 set_default_size: (500, 250),
139 set_child: Some(model.button.widget()),
140 }
141 }
142
143 fn init(
144 _init: Self::Init,
145 root: Self::Root,
146 sender: ComponentSender<Self>,
147 ) -> ComponentParts<Self> {
148 let button = Button::builder()
149 .launch(())
150 .forward(sender.input_sender(), identity);
151 let model = App { button };
152 let widgets = view_output!();
153 ComponentParts { model, widgets }
154 }
155
156 fn update(&mut self, _msg: Self::Input, _sender: ComponentSender<Self>) {}
157}
158
159fn main() {
160 let app = RelmApp::new("relm4.example.transient_dialog");
161 app.run::<App>(());
162}