gio/
action_map.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{clone, prelude::*};
4
5use crate::{prelude::*, ActionEntry, ActionMap, SimpleAction};
6
7mod sealed {
8    pub trait Sealed {}
9    impl<T: super::IsA<super::ActionMap>> Sealed for T {}
10}
11
12pub trait ActionMapExtManual: sealed::Sealed + IsA<ActionMap> {
13    /// A convenience function for creating multiple [`SimpleAction`][crate::SimpleAction]
14    /// instances and adding them to a [`ActionMap`][crate::ActionMap].
15    ///
16    /// Each action is constructed as per one [`ActionEntry`][crate::ActionEntry].
17    ///
18    /// **⚠️ The following code is in c ⚠️**
19    ///
20    /// ```c
21    /// static void
22    /// activate_quit (GSimpleAction *simple,
23    ///                GVariant      *parameter,
24    ///                gpointer       user_data)
25    /// {
26    ///   exit (0);
27    /// }
28    ///
29    /// static void
30    /// activate_print_string (GSimpleAction *simple,
31    ///                        GVariant      *parameter,
32    ///                        gpointer       user_data)
33    /// {
34    ///   g_print ("%s\n", g_variant_get_string (parameter, NULL));
35    /// }
36    ///
37    /// static GActionGroup *
38    /// create_action_group (void)
39    /// {
40    ///   const GActionEntry entries[] = {
41    ///     { "quit",         activate_quit              },
42    ///     { "print-string", activate_print_string, "s" }
43    ///   };
44    ///   GSimpleActionGroup *group;
45    ///
46    ///   group = g_simple_action_group_new ();
47    ///   g_action_map_add_action_entries (G_ACTION_MAP (group), entries, G_N_ELEMENTS (entries), NULL);
48    ///
49    ///   return G_ACTION_GROUP (group);
50    /// }
51    /// ```
52    /// ## `entries`
53    /// a pointer to
54    ///   the first item in an array of [`ActionEntry`][crate::ActionEntry] structs
55    #[doc(alias = "g_action_map_add_action_entries")]
56    fn add_action_entries(&self, entries: impl IntoIterator<Item = ActionEntry<Self>>) {
57        for entry in entries.into_iter() {
58            let action = if let Some(state) = entry.state() {
59                SimpleAction::new_stateful(entry.name(), entry.parameter_type(), state)
60            } else {
61                SimpleAction::new(entry.name(), entry.parameter_type())
62            };
63            let action_map = self.as_ref();
64            if let Some(callback) = entry.activate {
65                action.connect_activate(clone!(
66                    #[weak]
67                    action_map,
68                    move |action, state| {
69                        // safe to unwrap as O: IsA<ActionMap>
70                        callback(action_map.downcast_ref::<Self>().unwrap(), action, state);
71                    }
72                ));
73            }
74            if let Some(callback) = entry.change_state {
75                action.connect_change_state(clone!(
76                    #[weak]
77                    action_map,
78                    move |action, state| {
79                        // safe to unwrap as O: IsA<ActionMap>
80                        callback(action_map.downcast_ref::<Self>().unwrap(), action, state);
81                    }
82                ));
83            }
84            self.as_ref().add_action(&action);
85        }
86    }
87}
88
89impl<O: IsA<ActionMap>> ActionMapExtManual for O {}