relm4/actions/
traits.rs

1use gtk::prelude::ToVariant;
2
3/// Trait used to specify the group name in [`ActionName`].
4pub trait ActionGroupName {
5    /// The name of the group.
6    const NAME: &'static str;
7}
8
9/// Trait for marking stateless actions.
10pub trait EmptyType {}
11
12impl EmptyType for () {}
13
14/// Define the name of an action.
15pub trait ActionName {
16    /// The group of this action.
17    type Group: ActionGroupName;
18
19    /// Target value type for passing values to this action.
20    ///
21    /// Use [`()`] for actions without target value.
22    type Target;
23
24    /// State type of this action.
25    ///
26    /// Use [`()`] for stateless actions.
27    type State;
28
29    /// The name of the action.
30    const NAME: &'static str;
31
32    /// The full action name (group.action).
33    #[must_use]
34    fn action_name() -> String {
35        format!("{}.{}", Self::Group::NAME, Self::NAME)
36    }
37}
38
39/// Type safe interface for [`gtk::prelude::ActionableExt`].
40pub trait ActionablePlus {
41    /// Set a new stateful action with a default state value.
42    fn set_action<A: ActionName>(&self, value: A::Target)
43    where
44        A::Target: ToVariant;
45
46    /// Set a new stateless action.
47    fn set_stateless_action<A: ActionName>(&self, unit_type: &())
48    where
49        A::Target: EmptyType;
50}
51
52impl<W: gtk::prelude::ActionableExt> ActionablePlus for W {
53    fn set_action<A: ActionName>(&self, value: A::Target)
54    where
55        A::Target: ToVariant,
56    {
57        self.set_action_name(Some(A::action_name().as_str()));
58        self.set_action_target_value(Some(&value.to_variant()));
59    }
60
61    fn set_stateless_action<A: ActionName>(&self, _unit_type: &())
62    where
63        A::Target: EmptyType,
64    {
65        self.set_action_name(Some(A::action_name().as_str()));
66    }
67}
68
69/// Safe interface for [`gtk::prelude::GtkApplicationExt`].
70pub trait AccelsPlus {
71    /// Set keyboard accelerator for a certain action.
72    fn set_accelerators_for_action<A: ActionName>(&self, value: &[&str])
73    where
74        A::Target: EmptyType;
75}
76
77impl<W: gtk::prelude::GtkApplicationExt> AccelsPlus for W {
78    fn set_accelerators_for_action<A: ActionName>(&self, accel_codes: &[&str])
79    where
80        A::Target: EmptyType,
81    {
82        self.set_accels_for_action(A::action_name().as_str(), accel_codes);
83    }
84}