relm4/factory/widgets/traits.rs
1use gtk::prelude::IsA;
2use std::fmt::Debug;
3
4/// A trait implemented for GTK4 widgets that allows a factory to create and remove widgets.
5pub trait FactoryView: IsA<gtk::Widget> {
6 /// The widget returned when inserting a widget.
7 ///
8 /// This doesn't matter on containers like [`gtk::Box`].
9 /// However, widgets such as [`gtk::Stack`] return a [`gtk::StackPage`]
10 /// which might be used to set additional parameters.
11 ///
12 /// Therefore, this "returned widget" is explicitly handled here.
13 type ReturnedWidget: Debug + std::hash::Hash;
14
15 /// Widget type that is attached to the container
16 /// and also the root of the components.
17 type Children: Debug + AsRef<Self::Children>;
18
19 /// Position type used by this widget.
20 ///
21 /// For example [`GridPosition`] for [`gtk::Grid`] or `()` for [`gtk::Box`]
22 ///
23 /// [`GridPosition`]: crate::factory::positions::GridPosition
24 type Position;
25
26 /// Removes a widget.
27 fn factory_remove(&self, widget: &Self::ReturnedWidget);
28 /// Adds a new widget to self at the end.
29 fn factory_append(
30 &self,
31 widget: impl AsRef<Self::Children>,
32 position: &Self::Position,
33 ) -> Self::ReturnedWidget;
34
35 /// Add an widget to the front.
36 fn factory_prepend(
37 &self,
38 widget: impl AsRef<Self::Children>,
39 position: &Self::Position,
40 ) -> Self::ReturnedWidget;
41
42 /// Insert a widget after another widget.
43 fn factory_insert_after(
44 &self,
45 widget: impl AsRef<Self::Children>,
46 position: &Self::Position,
47 other: &Self::ReturnedWidget,
48 ) -> Self::ReturnedWidget;
49
50 /// Converts a returned widget to the children type.
51 ///
52 fn returned_widget_to_child(root_child: &Self::ReturnedWidget) -> Self::Children;
53
54 /// Move an item after another item.
55 fn factory_move_after(&self, widget: &Self::ReturnedWidget, other: &Self::ReturnedWidget);
56
57 /// Move an item to the start.
58 fn factory_move_start(&self, widget: &Self::ReturnedWidget);
59
60 /// Update the position inside positioned containers like [`gtk::Grid`].
61 fn factory_update_position(&self, _widget: &Self::ReturnedWidget, _position: &Self::Position) {}
62}
63
64/// Returns the position of an element inside a
65/// container like [`gtk::Grid`] where the position isn't
66/// clearly defined by the index.
67pub trait Position<Pos, Index> {
68 /// Returns the position.
69 ///
70 /// This function can be called very often
71 /// if widgets are moved a lot, so it should
72 /// be cheap to call.
73 fn position(&self, index: &Index) -> Pos;
74}
75
76impl<C, I> Position<(), I> for C {
77 fn position(&self, _index: &I) {}
78}
79
80/// Returns the position of an element inside a
81/// container like [`gtk::Grid`] where the position isn't
82/// clearly defined by the index.
83///
84/// Unlike [`Position`], this trait doesn't get access to self,
85/// because the model might not be initialized when the widgets
86/// are updated in the factory.
87pub trait AsyncPosition<Pos> {
88 /// Returns the position.
89 ///
90 /// This function can be called very often
91 /// if widgets are moved a lot, so it should
92 /// be cheap to call.
93 fn position(index: usize) -> Pos;
94}
95
96impl<C> AsyncPosition<()> for C {
97 fn position(_index: usize) {}
98}