gtk4/auto/expression.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, ExpressionWatch};
6use glib::{prelude::*, translate::*};
7use std::boxed::Box as Box_;
8
9glib::wrapper! {
10 /// Provides a way to describe references to values.
11 ///
12 /// An important aspect of expressions is that the value can be obtained
13 /// from a source that is several steps away. For example, an expression
14 /// may describe ‘the value of property A of `object1`, which is itself the
15 /// value of a property of `object2`’. And `object1` may not even exist yet
16 /// at the time that the expression is created. This is contrast to `GObject`
17 /// property bindings, which can only create direct connections between
18 /// the properties of two objects that must both exist for the duration
19 /// of the binding.
20 ///
21 /// An expression needs to be "evaluated" to obtain the value that it currently
22 /// refers to. An evaluation always happens in the context of a current object
23 /// called `this` (it mirrors the behavior of object-oriented languages),
24 /// which may or may not influence the result of the evaluation. Use
25 /// [`evaluate()`][Self::evaluate()] for evaluating an expression.
26 ///
27 /// Various methods for defining expressions exist, from simple constants via
28 /// [`ConstantExpression::new()`][crate::ConstantExpression::new()] to looking up properties in a `GObject`
29 /// (even recursively) via [`PropertyExpression::new()`][crate::PropertyExpression::new()] or providing
30 /// custom functions to transform and combine expressions via
31 /// [`ClosureExpression::new()`][crate::ClosureExpression::new()].
32 ///
33 /// Here is an example of a complex expression:
34 ///
35 /// **⚠️ The following code is in c ⚠️**
36 ///
37 /// ```c
38 /// color_expr = gtk_property_expression_new (GTK_TYPE_LIST_ITEM,
39 /// NULL, "item");
40 /// expression = gtk_property_expression_new (GTK_TYPE_COLOR,
41 /// color_expr, "name");
42 /// ```
43 ///
44 /// when evaluated with `this` being a [`ListItem`][crate::ListItem], it will obtain the
45 /// "item" property from the [`ListItem`][crate::ListItem], and then obtain the "name" property
46 /// from the resulting object (which is assumed to be of type `GTK_TYPE_COLOR`).
47 ///
48 /// A more concise way to describe this would be
49 ///
50 /// ```text
51 /// this->item->name
52 /// ```
53 ///
54 /// The most likely place where you will encounter expressions is in the context
55 /// of list models and list widgets using them. For example, [`DropDown`][crate::DropDown] is
56 /// evaluating a [`Expression`][crate::Expression] to obtain strings from the items in its model
57 /// that it can then use to match against the contents of its search entry.
58 /// [`StringFilter`][crate::StringFilter] is using a [`Expression`][crate::Expression] for similar reasons.
59 ///
60 /// By default, expressions are not paying attention to changes and evaluation is
61 /// just a snapshot of the current state at a given time. To get informed about
62 /// changes, an expression needs to be "watched" via a [`ExpressionWatch`][crate::ExpressionWatch],
63 /// which will cause a callback to be called whenever the value of the expression may
64 /// have changed; [`watch()`][Self::watch()] starts watching an expression, and
65 /// [`ExpressionWatch::unwatch()`][crate::ExpressionWatch::unwatch()] stops.
66 ///
67 /// Watches can be created for automatically updating the property of an object,
68 /// similar to GObject's `GBinding` mechanism, by using [`bind()`][Self::bind()].
69 ///
70 /// ## GtkExpression in GObject properties
71 ///
72 /// In order to use a [`Expression`][crate::Expression] as a `GObject` property, you must use the
73 /// `param_spec_expression()` when creating a `GParamSpec` to install in the
74 /// `GObject` class being defined; for instance:
75 ///
76 /// **⚠️ The following code is in c ⚠️**
77 ///
78 /// ```c
79 /// obj_props[PROP_EXPRESSION] =
80 /// gtk_param_spec_expression ("expression",
81 /// "Expression",
82 /// "The expression used by the widget",
83 /// G_PARAM_READWRITE |
84 /// G_PARAM_STATIC_STRINGS |
85 /// G_PARAM_EXPLICIT_NOTIFY);
86 /// ```
87 ///
88 /// When implementing the `GObjectClass.set_property` and `GObjectClass.get_property`
89 /// virtual functions, you must use `value_get_expression()`, to retrieve the
90 /// stored [`Expression`][crate::Expression] from the `GValue` container, and `value_set_expression()`,
91 /// to store the [`Expression`][crate::Expression] into the `GValue`; for instance:
92 ///
93 /// **⚠️ The following code is in c ⚠️**
94 ///
95 /// ```c
96 /// // in set_property()...
97 /// case PROP_EXPRESSION:
98 /// foo_widget_set_expression (foo, gtk_value_get_expression (value));
99 /// break;
100 ///
101 /// // in get_property()...
102 /// case PROP_EXPRESSION:
103 /// gtk_value_set_expression (value, foo->expression);
104 /// break;
105 /// ```
106 ///
107 /// ## GtkExpression in .ui files
108 ///
109 /// [`Builder`][crate::Builder] has support for creating expressions. The syntax here can be used where
110 /// a [`Expression`][crate::Expression] object is needed like in a `<property>` tag for an expression
111 /// property, or in a `<binding name="property">` tag to bind a property to an expression.
112 ///
113 /// To create a property expression, use the `<lookup>` element. It can have a `type`
114 /// attribute to specify the object type, and a `name` attribute to specify the property
115 /// to look up. The content of `<lookup>` can either be a string that specifies the name
116 /// of the object to use, an element specifying an expression to provide an object, or
117 /// empty to use the `this` object.
118 ///
119 /// Example:
120 ///
121 /// ```xml
122 /// <lookup name='search'>string_filter</lookup>
123 /// ```
124 ///
125 /// Since the `<lookup>` element creates an expression and its element content can
126 /// itself be an expression, this means that `<lookup>` tags can also be nested.
127 /// This is a common idiom when dealing with [`ListItem`][crate::ListItem]s. See
128 /// [`BuilderListItemFactory`][crate::BuilderListItemFactory] for an example of this technique.
129 ///
130 /// To create a constant expression, use the `<constant>` element. If the type attribute
131 /// is specified, the element content is interpreted as a value of that type. Otherwise,
132 /// it is assumed to be an object. For instance:
133 ///
134 /// ```xml
135 /// <constant>string_filter</constant>
136 /// <constant type='gchararray'>Hello, world</constant>
137 /// ```
138 ///
139 /// String (`type='gchararray'`) constants can be marked for translation with the
140 /// `translatable=` attribute, and will then be looked up in the
141 /// [`translation-domain`][struct@crate::Builder#translation-domain] when the expression is constructed.
142 ///
143 /// ```xml
144 /// <constant type='gchararray' translatable='yes'>I'm translatable!</constant>
145 /// ```
146 ///
147 /// As with other translatable strings in [type@Gtk.Builder], constants can
148 /// also have a context and/or translation comment:
149 ///
150 /// ```xml
151 /// <constant type='gchararray'
152 /// translatable='yes'
153 /// context='example'
154 /// comments='A sample string'>I'm translatable!</constant>
155 /// ```
156 ///
157 /// To create a closure expression, use the `<closure>` element. The `function`
158 /// attribute specifies what function to use for the closure, and the `type`
159 /// attribute specifies its return type. The content of the element contains the
160 /// expressions for the parameters. For instance:
161 ///
162 /// ```xml
163 /// <closure type='gchararray' function='combine_args_somehow'>
164 /// <constant type='gchararray'>File size:</constant>
165 /// <lookup type='GFile' name='size'>myfile</lookup>
166 /// </closure>
167 /// ```
168 ///
169 /// To create a property binding, use the `<binding>` element in place of where a
170 /// `<property>` tag would ordinarily be used. The `name` and `object` attributes are
171 /// supported. The `name` attribute is required, and pertains to the applicable property
172 /// name. The `object` attribute is optional. If provided, it will use the specified object
173 /// as the `this` object when the expression is evaluated. Here is an example in which the
174 /// `label` property of a [`Label`][crate::Label] is bound to the `string` property of another arbitrary
175 /// object:
176 ///
177 /// ```xml
178 /// <object class='GtkLabel'>
179 /// <binding name='label'>
180 /// <lookup name='string'>some_other_object</lookup>
181 /// </binding>
182 /// </object>
183 /// ```
184 ///
185 /// This is an Abstract Base Class, you cannot instantiate it.
186 #[doc(alias = "GtkExpression")]
187 pub struct Expression(Shared<ffi::GtkExpression>);
188
189 match fn {
190 ref => |ptr| ffi::gtk_expression_ref(ptr),
191 unref => |ptr| ffi::gtk_expression_unref(ptr),
192 }
193}
194
195impl StaticType for Expression {
196 fn static_type() -> glib::Type {
197 unsafe { from_glib(ffi::gtk_expression_get_type()) }
198 }
199}
200
201impl Expression {
202 pub const NONE: Option<&'static Expression> = None;
203
204 /// Bind `target`'s property named `property` to `self`.
205 ///
206 /// The value that `self` evaluates to is set via `g_object_set()` on
207 /// `target`. This is repeated whenever `self` changes to ensure that
208 /// the object's property stays synchronized with `self`.
209 ///
210 /// If `self`'s evaluation fails, `target`'s `property` is not updated.
211 /// You can ensure that this doesn't happen by using a fallback
212 /// expression.
213 ///
214 /// Note that this function takes ownership of `self`. If you want
215 /// to keep it around, you should `Gtk::Expression::ref()` it beforehand.
216 /// ## `target`
217 /// the target object to bind to
218 /// ## `property`
219 /// name of the property on `target` to bind to
220 /// ## `this_`
221 /// the this argument for
222 /// the evaluation of `self`
223 ///
224 /// # Returns
225 ///
226 /// a [`ExpressionWatch`][crate::ExpressionWatch]
227 #[doc(alias = "gtk_expression_bind")]
228 pub fn bind(
229 &self,
230 target: &impl IsA<glib::Object>,
231 property: &str,
232 this_: Option<&impl IsA<glib::Object>>,
233 ) -> ExpressionWatch {
234 unsafe {
235 from_glib_none(ffi::gtk_expression_bind(
236 self.as_ref().to_glib_full(),
237 target.as_ref().to_glib_none().0,
238 property.to_glib_none().0,
239 this_.map(|p| p.as_ref()).to_glib_none().0,
240 ))
241 }
242 }
243
244 /// Gets the `GType` that this expression evaluates to.
245 ///
246 /// This type is constant and will not change over the lifetime
247 /// of this expression.
248 ///
249 /// # Returns
250 ///
251 /// The type returned from [`evaluate()`][Self::evaluate()]
252 #[doc(alias = "gtk_expression_get_value_type")]
253 #[doc(alias = "get_value_type")]
254 pub fn value_type(&self) -> glib::types::Type {
255 unsafe {
256 from_glib(ffi::gtk_expression_get_value_type(
257 self.as_ref().to_glib_none().0,
258 ))
259 }
260 }
261
262 /// Checks if the expression is static.
263 ///
264 /// A static expression will never change its result when
265 /// [`evaluate()`][Self::evaluate()] is called on it with the same arguments.
266 ///
267 /// That means a call to [`watch()`][Self::watch()] is not necessary because
268 /// it will never trigger a notify.
269 ///
270 /// # Returns
271 ///
272 /// `TRUE` if the expression is static
273 #[doc(alias = "gtk_expression_is_static")]
274 pub fn is_static(&self) -> bool {
275 unsafe {
276 from_glib(ffi::gtk_expression_is_static(
277 self.as_ref().to_glib_none().0,
278 ))
279 }
280 }
281
282 /// Watch the given `expression` for changes.
283 ///
284 /// The @notify function will be called whenever the evaluation of `self`
285 /// may have changed.
286 ///
287 /// GTK cannot guarantee that the evaluation did indeed change when the @notify
288 /// gets invoked, but it guarantees the opposite: When it did in fact change,
289 /// the @notify will be invoked.
290 /// ## `this_`
291 /// the `this` argument to
292 /// watch
293 /// ## `notify`
294 /// callback to invoke when the expression changes
295 ///
296 /// # Returns
297 ///
298 /// The newly installed watch. Note that the only
299 /// reference held to the watch will be released when the watch is unwatched
300 /// which can happen automatically, and not just via
301 /// [`ExpressionWatch::unwatch()`][crate::ExpressionWatch::unwatch()]. You should call `Gtk::ExpressionWatch::ref()`
302 /// if you want to keep the watch around.
303 #[doc(alias = "gtk_expression_watch")]
304 pub fn watch<P: Fn() + 'static>(
305 &self,
306 this_: Option<&impl IsA<glib::Object>>,
307 notify: P,
308 ) -> ExpressionWatch {
309 let notify_data: Box_<P> = Box_::new(notify);
310 unsafe extern "C" fn notify_func<P: Fn() + 'static>(user_data: glib::ffi::gpointer) {
311 let callback = &*(user_data as *mut P);
312 (*callback)()
313 }
314 let notify = Some(notify_func::<P> as _);
315 unsafe extern "C" fn user_destroy_func<P: Fn() + 'static>(data: glib::ffi::gpointer) {
316 let _callback = Box_::from_raw(data as *mut P);
317 }
318 let destroy_call4 = Some(user_destroy_func::<P> as _);
319 let super_callback0: Box_<P> = notify_data;
320 unsafe {
321 from_glib_none(ffi::gtk_expression_watch(
322 self.as_ref().to_glib_none().0,
323 this_.map(|p| p.as_ref()).to_glib_none().0,
324 notify,
325 Box_::into_raw(super_callback0) as *mut _,
326 destroy_call4,
327 ))
328 }
329 }
330}