Skip to main content

gtk/
accel_group.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::AccelFlags;
4use crate::AccelGroup;
5use glib::object::{Cast, IsA};
6use glib::translate::*;
7use glib::ToValue;
8
9mod sealed {
10    pub trait Sealed {}
11    impl<T: glib::IsA<crate::AccelGroup>> Sealed for T {}
12}
13
14pub trait AccelGroupExtManual: IsA<AccelGroup> + sealed::Sealed + 'static {
15    /// Installs an accelerator in this group. When `self` is being
16    /// activated in response to a call to [`accel_groups_activate()`][crate::accel_groups_activate()],
17    /// `closure` will be invoked if the `accel_key` and `accel_mods` from
18    /// [`accel_groups_activate()`][crate::accel_groups_activate()] match those of this connection.
19    ///
20    /// The signature used for the `closure` is that of `GtkAccelGroupActivate`.
21    ///
22    /// Note that, due to implementation details, a single closure can
23    /// only be connected to one accelerator group.
24    /// ## `accel_key`
25    /// key value of the accelerator
26    /// ## `accel_mods`
27    /// modifier combination of the accelerator
28    /// ## `accel_flags`
29    /// a flag mask to configure this accelerator
30    /// ## `closure`
31    /// closure to be executed upon accelerator activation
32    fn connect_accel_group<F>(
33        &self,
34        accel_key: u32,
35        accel_mods: gdk::ModifierType,
36        accel_flags: AccelFlags,
37        func: F,
38    ) -> glib::Closure
39    where
40        F: Fn(&Self, &glib::Object, u32, gdk::ModifierType) -> bool + 'static,
41    {
42        let closure = glib::Closure::new_local(move |values| {
43            assert_eq!(values.len(), 4);
44            let s = values[0]
45                .get::<AccelGroup>()
46                .expect("Wrong argument type for first closure argument");
47            let s = s
48                .downcast::<Self>()
49                .expect("Wrong argument type for first closure argument");
50
51            let obj = values[1]
52                .get::<glib::Object>()
53                .expect("Wrong argument type for second closure argument");
54            let accel_key = values[2]
55                .get::<u32>()
56                .expect("Wrong argument type for third closure argument");
57            let accel_mods = values[3]
58                .get::<gdk::ModifierType>()
59                .expect("Wrong argument type for fourth closure argument");
60
61            let ret = func(&s, &obj, accel_key, accel_mods);
62
63            Some(ret.to_value())
64        });
65
66        unsafe {
67            ffi::gtk_accel_group_connect(
68                self.as_ref().to_glib_none().0,
69                accel_key,
70                accel_mods.into_glib(),
71                accel_flags.into_glib(),
72                closure.to_glib_none().0,
73            );
74        }
75
76        closure
77    }
78
79    /// Installs an accelerator in this group, using an accelerator path
80    /// to look up the appropriate key and modifiers (see
81    /// `gtk_accel_map_add_entry()`). When `self` is being activated
82    /// in response to a call to [`accel_groups_activate()`][crate::accel_groups_activate()], `closure` will
83    /// be invoked if the `accel_key` and `accel_mods` from
84    /// [`accel_groups_activate()`][crate::accel_groups_activate()] match the key and modifiers for the path.
85    ///
86    /// The signature used for the `closure` is that of `GtkAccelGroupActivate`.
87    ///
88    /// Note that `accel_path` string will be stored in a `GQuark`. Therefore,
89    /// if you pass a static string, you can save some memory by interning it
90    /// first with `g_intern_static_string()`.
91    /// ## `accel_path`
92    /// path used for determining key and modifiers
93    /// ## `closure`
94    /// closure to be executed upon accelerator activation
95    fn connect_accel_group_by_path<F>(&self, accel_path: &str, func: F) -> glib::Closure
96    where
97        F: Fn(&Self, &glib::Object, u32, gdk::ModifierType) -> bool + 'static,
98    {
99        let closure = glib::Closure::new_local(move |values| {
100            assert_eq!(values.len(), 4);
101            let s = values[0]
102                .get::<AccelGroup>()
103                .expect("Wrong argument type for first closure argument");
104            let s = s
105                .downcast::<Self>()
106                .expect("Wrong argument type for first closure argument");
107            let obj = values[1]
108                .get::<glib::Object>()
109                .expect("Wrong argument type for second closure argument");
110            let accel_key = values[2]
111                .get::<u32>()
112                .expect("Wrong argument type for third closure argument");
113            let accel_mods = values[3]
114                .get::<gdk::ModifierType>()
115                .expect("Wrong argument type for fourth closure argument");
116
117            let ret = func(&s, &obj, accel_key, accel_mods);
118
119            Some(ret.to_value())
120        });
121
122        unsafe {
123            ffi::gtk_accel_group_connect_by_path(
124                self.as_ref().to_glib_none().0,
125                accel_path.to_glib_none().0,
126                closure.to_glib_none().0,
127            );
128        }
129
130        closure
131    }
132}
133
134impl<O: IsA<AccelGroup>> AccelGroupExtManual for O {}