relm4/factory/widgets/
gtk.rs

1use gtk::prelude::{BoxExt, Cast, FlowBoxChildExt, GridExt, ListBoxRowExt, WidgetExt};
2
3use crate::factory::{FactoryView, positions};
4
5impl FactoryView for gtk::Box {
6    type Children = gtk::Widget;
7    type ReturnedWidget = gtk::Widget;
8    type Position = ();
9
10    fn factory_remove(&self, widget: &Self::ReturnedWidget) {
11        self.remove(widget);
12    }
13
14    fn factory_append(
15        &self,
16        widget: impl AsRef<Self::Children>,
17        _position: &(),
18    ) -> Self::ReturnedWidget {
19        self.append(widget.as_ref());
20        widget.as_ref().clone()
21    }
22
23    fn factory_prepend(
24        &self,
25        widget: impl AsRef<Self::Children>,
26        _position: &(),
27    ) -> Self::ReturnedWidget {
28        self.prepend(widget.as_ref());
29        widget.as_ref().clone()
30    }
31
32    fn factory_insert_after(
33        &self,
34        widget: impl AsRef<Self::Children>,
35        _position: &(),
36        other: &Self::ReturnedWidget,
37    ) -> Self::ReturnedWidget {
38        self.insert_child_after(widget.as_ref(), Some(other));
39        widget.as_ref().clone()
40    }
41
42    fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children {
43        returned_widget.clone()
44    }
45
46    fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) {
47        self.reorder_child_after(widget, Some(other));
48    }
49
50    fn factory_move_start(&self, widget: &Self::ReturnedWidget) {
51        self.reorder_child_after(widget, None::<&gtk::Widget>);
52    }
53}
54
55impl FactoryView for gtk::Grid {
56    type Children = gtk::Widget;
57    type ReturnedWidget = gtk::Widget;
58    type Position = positions::GridPosition;
59
60    fn factory_remove(&self, widget: &Self::ReturnedWidget) {
61        self.remove(widget);
62    }
63
64    fn factory_append(
65        &self,
66        widget: impl AsRef<Self::Children>,
67        position: &Self::Position,
68    ) -> Self::ReturnedWidget {
69        self.attach(
70            widget.as_ref(),
71            position.column,
72            position.row,
73            position.width,
74            position.height,
75        );
76        widget.as_ref().clone()
77    }
78
79    fn factory_prepend(
80        &self,
81        widget: impl AsRef<Self::Children>,
82        position: &Self::Position,
83    ) -> Self::ReturnedWidget {
84        self.factory_append(widget, position)
85    }
86
87    fn factory_insert_after(
88        &self,
89        widget: impl AsRef<Self::Children>,
90        position: &Self::Position,
91        _other: &Self::ReturnedWidget,
92    ) -> Self::ReturnedWidget {
93        self.factory_append(widget, position)
94    }
95
96    fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {}
97
98    fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {}
99
100    fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children {
101        returned_widget.clone()
102    }
103
104    fn factory_update_position(&self, widget: &Self::ReturnedWidget, position: &Self::Position) {
105        self.factory_remove(widget);
106        self.factory_append(widget, position);
107    }
108}
109
110impl FactoryView for gtk::Stack {
111    type Children = gtk::Widget;
112    type ReturnedWidget = gtk::StackPage;
113    type Position = ();
114
115    fn factory_remove(&self, widget: &Self::ReturnedWidget) {
116        self.remove(&widget.child());
117    }
118
119    fn factory_append(
120        &self,
121        widget: impl AsRef<Self::Children>,
122        _position: &Self::Position,
123    ) -> Self::ReturnedWidget {
124        self.add_child(widget.as_ref())
125    }
126
127    fn factory_prepend(
128        &self,
129        widget: impl AsRef<Self::Children>,
130        _position: &(),
131    ) -> Self::ReturnedWidget {
132        self.add_child(widget.as_ref())
133    }
134
135    fn factory_insert_after(
136        &self,
137        widget: impl AsRef<Self::Children>,
138        _position: &(),
139        _other: &Self::ReturnedWidget,
140    ) -> Self::ReturnedWidget {
141        self.add_child(widget.as_ref())
142    }
143
144    fn factory_move_after(&self, _widget: &Self::ReturnedWidget, _other: &Self::ReturnedWidget) {}
145
146    fn factory_move_start(&self, _widget: &Self::ReturnedWidget) {}
147
148    fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children {
149        returned_widget.child()
150    }
151}
152
153impl FactoryView for gtk::ListBox {
154    type Children = gtk::Widget;
155    type ReturnedWidget = gtk::ListBoxRow;
156    type Position = ();
157
158    fn factory_remove(&self, widget: &Self::ReturnedWidget) {
159        widget.set_child(None::<&gtk::Widget>);
160        self.remove(widget);
161    }
162
163    fn factory_append(
164        &self,
165        widget: impl AsRef<Self::Children>,
166        _position: &(),
167    ) -> Self::ReturnedWidget {
168        let widget = widget.as_ref();
169
170        self.append(widget);
171
172        match widget.downcast_ref::<gtk::ListBoxRow>() {
173            Some(row) => row.clone(),
174            None => widget.parent().unwrap().downcast().unwrap(),
175        }
176    }
177
178    fn factory_prepend(
179        &self,
180        widget: impl AsRef<Self::Children>,
181        _position: &(),
182    ) -> Self::ReturnedWidget {
183        let widget = widget.as_ref();
184
185        self.prepend(widget);
186
187        match widget.downcast_ref::<gtk::ListBoxRow>() {
188            Some(row) => row.clone(),
189            None => widget.parent().unwrap().downcast().unwrap(),
190        }
191    }
192
193    fn factory_insert_after(
194        &self,
195        widget: impl AsRef<Self::Children>,
196        _position: &(),
197        other: &Self::ReturnedWidget,
198    ) -> Self::ReturnedWidget {
199        let widget = widget.as_ref();
200
201        self.insert(widget, other.index() + 1);
202
203        match widget.downcast_ref::<gtk::ListBoxRow>() {
204            Some(row) => row.clone(),
205            None => widget.parent().unwrap().downcast().unwrap(),
206        }
207    }
208
209    fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) {
210        self.remove(widget);
211        self.insert(widget, other.index() + 1);
212    }
213
214    fn factory_move_start(&self, widget: &Self::ReturnedWidget) {
215        self.remove(widget);
216        self.prepend(widget);
217    }
218
219    fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children {
220        returned_widget
221            .child()
222            .unwrap_or_else(|| returned_widget.upcast_ref::<gtk::Widget>().clone())
223    }
224}
225
226impl FactoryView for gtk::FlowBox {
227    type Children = gtk::Widget;
228    type ReturnedWidget = gtk::FlowBoxChild;
229    type Position = ();
230
231    fn factory_remove(&self, widget: &Self::ReturnedWidget) {
232        widget.set_child(None::<&gtk::Widget>);
233        self.remove(widget);
234    }
235
236    fn factory_append(
237        &self,
238        widget: impl AsRef<Self::Children>,
239        _position: &(),
240    ) -> Self::ReturnedWidget {
241        let widget = widget.as_ref();
242
243        self.insert(widget, -1);
244
245        match widget.downcast_ref::<gtk::FlowBoxChild>() {
246            Some(child) => child.clone(),
247            None => widget.parent().unwrap().downcast().unwrap(),
248        }
249    }
250
251    fn factory_prepend(
252        &self,
253        widget: impl AsRef<Self::Children>,
254        _position: &(),
255    ) -> Self::ReturnedWidget {
256        let widget = widget.as_ref();
257
258        self.insert(widget, 0);
259
260        match widget.downcast_ref::<gtk::FlowBoxChild>() {
261            Some(child) => child.clone(),
262            None => widget.parent().unwrap().downcast().unwrap(),
263        }
264    }
265
266    fn factory_insert_after(
267        &self,
268        widget: impl AsRef<Self::Children>,
269        _position: &(),
270        other: &Self::ReturnedWidget,
271    ) -> Self::ReturnedWidget {
272        let widget = widget.as_ref();
273
274        self.insert(widget, other.index() + 1);
275
276        match widget.downcast_ref::<gtk::FlowBoxChild>() {
277            Some(child) => child.clone(),
278            None => widget.parent().unwrap().downcast().unwrap(),
279        }
280    }
281
282    fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget) {
283        self.remove(widget);
284        self.insert(widget, other.index() + 1);
285    }
286
287    fn factory_move_start(&self, widget: &Self::ReturnedWidget) {
288        self.remove(widget);
289        self.insert(widget, 0);
290    }
291
292    fn returned_widget_to_child(returned_widget: &Self::ReturnedWidget) -> Self::Children {
293        returned_widget
294            .child()
295            .unwrap_or_else(|| returned_widget.upcast_ref::<gtk::Widget>().clone())
296    }
297}
298
299// impl FactoryView<gtk::TreeViewColumn> for gtk::TreeView {
300//     type Position = ();
301//     type Root = gtk::TreeViewColumn;
302
303//     fn add(&self, widget: &gtk::TreeViewColumn, _position: &()) -> gtk::TreeViewColumn {
304//         self.insert_column(widget, -1);
305//         widget.clone()
306//     }
307
308//     fn remove(&self, widget: &gtk::TreeViewColumn) {
309//         self.remove_column(widget);
310//     }
311// }
312
313// impl<Widget> FactoryView<Widget> for gtk::Stack
314// where
315//     Widget: glib::IsA<gtk::Widget>,
316// {
317//     type Position = StackPageInfo;
318//     type Root = Widget;
319
320//     fn add(&self, widget: &Widget, position: &StackPageInfo) -> Widget {
321//         if let Some(title) = &position.title {
322//             self.add_titled(widget, position.name.as_deref(), title);
323//         } else {
324//             self.add_named(widget, position.name.as_deref());
325//         }
326//         widget.clone()
327//     }
328
329//     fn remove(&self, widget: &Widget) {
330//         self.remove(widget);
331//     }
332// }
333
334// impl<Widget> FactoryView<Widget> for gtk::Fixed
335// where
336//     Widget: glib::IsA<gtk::Widget>,
337// {
338//     type Position = FixedPosition;
339//     type Root = Widget;
340
341//     fn add(&self, widget: &Widget, position: &FixedPosition) -> Widget {
342//         gtk::prelude::FixedExt::put(self, widget, position.x, position.y);
343//         widget.clone()
344//     }
345
346//     fn remove(&self, widget: &Widget) {
347//         gtk::prelude::FixedExt::remove(self, widget);
348//     }
349// }
350
351// impl<Widget> FactoryView<Widget> for gtk::Grid
352// where
353//     Widget: glib::IsA<gtk::Widget>,
354// {
355//     type Position = GridPosition;
356//     type Root = Widget;
357
358//     fn add(&self, widget: &Widget, position: &GridPosition) -> Widget {
359//         self.attach(
360//             widget,
361//             position.column,
362//             position.row,
363//             position.width,
364//             position.height,
365//         );
366//         widget.clone()
367//     }
368
369//     fn remove(&self, widget: &Widget) {
370//         GridExt::remove(self, widget);
371//     }
372// }