1
- use crate :: { Settings , SettingsExt } ;
1
+ use crate :: { Settings , SettingsBindFlags , SettingsExt } ;
2
+ use glib:: prelude:: * ;
3
+ use glib:: translate:: { from_glib_borrow, from_glib_none, ToGlib , ToGlibPtr } ;
2
4
use glib:: variant:: FromVariant ;
3
5
use glib:: { BoolError , IsA , ToVariant } ;
4
6
7
+ pub struct BindingBuilder < ' a > {
8
+ settings : & ' a Settings ,
9
+ key : & ' a str ,
10
+ object : & ' a glib:: Object ,
11
+ property : & ' a str ,
12
+ flags : SettingsBindFlags ,
13
+ get_mapping : Option < Box < dyn Fn ( & glib:: Variant , glib:: Type ) -> Option < glib:: Value > > > ,
14
+ set_mapping : Option < Box < dyn Fn ( & glib:: Value , glib:: VariantType ) -> Option < glib:: Variant > > > ,
15
+ }
16
+
17
+ impl < ' a > BindingBuilder < ' a > {
18
+ pub fn flags ( mut self , flags : SettingsBindFlags ) -> Self {
19
+ self . flags = flags;
20
+ self
21
+ }
22
+
23
+ pub fn get_mapping < F : Fn ( & glib:: Variant , glib:: Type ) -> Option < glib:: Value > + ' static > (
24
+ mut self ,
25
+ f : F ,
26
+ ) -> Self {
27
+ self . get_mapping = Some ( Box :: new ( f) ) ;
28
+ self
29
+ }
30
+
31
+ pub fn set_mapping <
32
+ F : Fn ( & glib:: Value , glib:: VariantType ) -> Option < glib:: Variant > + ' static ,
33
+ > (
34
+ mut self ,
35
+ f : F ,
36
+ ) -> Self {
37
+ self . set_mapping = Some ( Box :: new ( f) ) ;
38
+ self
39
+ }
40
+
41
+ pub fn build ( self ) {
42
+ type Mappings = (
43
+ Option < Box < dyn Fn ( & glib:: Variant , glib:: Type ) -> Option < glib:: Value > > > ,
44
+ Option < Box < dyn Fn ( & glib:: Value , glib:: VariantType ) -> Option < glib:: Variant > > > ,
45
+ ) ;
46
+ unsafe extern "C" fn bind_with_mapping_get_trampoline (
47
+ value : * mut glib:: gobject_ffi:: GValue ,
48
+ variant : * mut glib:: ffi:: GVariant ,
49
+ user_data : glib:: ffi:: gpointer ,
50
+ ) -> glib:: ffi:: gboolean {
51
+ let user_data = & * ( user_data as * const Mappings ) ;
52
+ let f = user_data. 0 . as_ref ( ) . unwrap ( ) ;
53
+ let value = & mut * ( value as * mut glib:: Value ) ;
54
+ if let Some ( v) = f ( & * from_glib_borrow ( variant) , value. type_ ( ) ) {
55
+ * value = v;
56
+ true
57
+ } else {
58
+ false
59
+ }
60
+ . to_glib ( )
61
+ }
62
+ unsafe extern "C" fn bind_with_mapping_set_trampoline (
63
+ value : * const glib:: gobject_ffi:: GValue ,
64
+ variant_type : * const glib:: ffi:: GVariantType ,
65
+ user_data : glib:: ffi:: gpointer ,
66
+ ) -> * mut glib:: ffi:: GVariant {
67
+ let user_data = & * ( user_data as * const Mappings ) ;
68
+ let f = user_data. 1 . as_ref ( ) . unwrap ( ) ;
69
+ let value = & * ( value as * const glib:: Value ) ;
70
+ f ( value, from_glib_none ( variant_type) ) . to_glib_full ( )
71
+ }
72
+ unsafe extern "C" fn destroy_closure ( ptr : * mut libc:: c_void ) {
73
+ Box :: < Mappings > :: from_raw ( ptr as * mut _ ) ;
74
+ }
75
+ let get_trampoline: Option < unsafe extern "C" fn ( _, _, _) -> _ > =
76
+ if self . get_mapping . is_none ( ) {
77
+ None
78
+ } else {
79
+ Some ( bind_with_mapping_get_trampoline)
80
+ } ;
81
+ let set_trampoline: Option < unsafe extern "C" fn ( _, _, _) -> _ > =
82
+ if self . set_mapping . is_none ( ) {
83
+ None
84
+ } else {
85
+ Some ( bind_with_mapping_set_trampoline)
86
+ } ;
87
+ let mappings: Mappings = ( self . get_mapping , self . set_mapping ) ;
88
+ unsafe {
89
+ ffi:: g_settings_bind_with_mapping (
90
+ self . settings . to_glib_none ( ) . 0 ,
91
+ self . key . to_glib_none ( ) . 0 ,
92
+ self . object . to_glib_none ( ) . 0 ,
93
+ self . property . to_glib_none ( ) . 0 ,
94
+ self . flags . to_glib ( ) ,
95
+ get_trampoline,
96
+ set_trampoline,
97
+ Box :: into_raw ( Box :: new ( mappings) ) as * mut libc:: c_void ,
98
+ Some ( destroy_closure) ,
99
+ )
100
+ }
101
+ }
102
+ }
103
+
5
104
pub trait SettingsExtManual {
6
105
fn get < U : FromVariant > ( & self , key : & str ) -> U ;
7
106
8
107
fn set < U : ToVariant > ( & self , key : & str , value : & U ) -> Result < ( ) , BoolError > ;
108
+
109
+ #[ doc( alias = "g_settings_bind" ) ]
110
+ #[ doc( alias = "g_settings_bind_with_mapping" ) ]
111
+ fn bind < ' a , P : IsA < glib:: Object > > (
112
+ & ' a self ,
113
+ key : & ' a str ,
114
+ object : & ' a P ,
115
+ property : & ' a str ,
116
+ ) -> BindingBuilder < ' a > ;
9
117
}
10
118
11
119
impl < O : IsA < Settings > > SettingsExtManual for O {
@@ -23,6 +131,23 @@ impl<O: IsA<Settings>> SettingsExtManual for O {
23
131
fn set < U : ToVariant > ( & self , key : & str , value : & U ) -> Result < ( ) , BoolError > {
24
132
self . set_value ( key, & value. to_variant ( ) )
25
133
}
134
+
135
+ fn bind < ' a , P : IsA < glib:: Object > > (
136
+ & ' a self ,
137
+ key : & ' a str ,
138
+ object : & ' a P ,
139
+ property : & ' a str ,
140
+ ) -> BindingBuilder < ' a > {
141
+ BindingBuilder {
142
+ settings : self . upcast_ref ( ) ,
143
+ key,
144
+ object : object. upcast_ref ( ) ,
145
+ property,
146
+ flags : SettingsBindFlags :: DEFAULT ,
147
+ get_mapping : None ,
148
+ set_mapping : None ,
149
+ }
150
+ }
26
151
}
27
152
28
153
#[ cfg( test) ]
0 commit comments