Skip to main content

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::{ExpressionWatch, ffi};
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, and the
132    /// initial attribute can be specified to get the initial value for that type. Otherwise,
133    /// it is assumed to be an object. For instance:
134    ///
135    /// ```xml
136    ///   <constant>string_filter</constant>
137    ///   <constant type='gchararray'>Hello, world</constant>
138    ///   <constant type='gchararray' initial='true' /> <!-- NULL -->
139    /// ```
140    ///
141    /// String (`type='gchararray'`) constants can be marked for translation with the
142    /// `translatable=` attribute, and will then be looked up in the
143    /// [`translation-domain`][struct@crate::Builder#translation-domain] when the expression is constructed.
144    ///
145    /// ```xml
146    ///   <constant type='gchararray' translatable='yes'>I'm translatable!</constant>
147    /// ```
148    ///
149    /// As with other translatable strings in [type@Gtk.Builder], constants can
150    /// also have a context and/or translation comment:
151    ///
152    /// ```xml
153    ///   <constant type='gchararray'
154    ///             translatable='yes'
155    ///             context='example'
156    ///             comments='A sample string'>I'm translatable!</constant>
157    /// ```
158    ///
159    /// To create a closure expression, use the `<closure>` element. The `function`
160    /// attribute specifies what function to use for the closure, and the `type`
161    /// attribute specifies its return type. The content of the element contains the
162    /// expressions for the parameters. For instance:
163    ///
164    /// ```xml
165    ///   <closure type='gchararray' function='combine_args_somehow'>
166    ///     <constant type='gchararray'>File size:</constant>
167    ///     <lookup type='GFile' name='size'>myfile</lookup>
168    ///   </closure>
169    /// ```
170    ///
171    /// If an expression can fail, a `<try>` element can be used to provide fallbacks.
172    /// The expressions are tried from top to bottom until one of them succeeds.
173    /// If none of the expressions succeed, the expression fails as normal:
174    ///
175    /// ```xml
176    ///   <try>
177    ///     <lookup type='GtkWindow' name='title'>
178    ///       <lookup type='GtkLabel' name='root'></lookup>
179    ///     </lookup>
180    ///     <constant type='gchararray'>Hello World</constant>
181    ///   </try>
182    /// ```
183    ///
184    /// To create a property binding, use the `<binding>` element in place of where a
185    /// `<property>` tag would ordinarily be used. The `name` and `object` attributes are
186    /// supported. The `name` attribute is required, and pertains to the applicable property
187    /// name. The `object` attribute is optional. If provided, it will use the specified object
188    /// as the `this` object when the expression is evaluated. Here is an example in which the
189    /// `label` property of a [`Label`][crate::Label] is bound to the `string` property of another arbitrary
190    /// object:
191    ///
192    /// ```xml
193    ///   <object class='GtkLabel'>
194    ///     <binding name='label'>
195    ///       <lookup name='string'>some_other_object</lookup>
196    ///     </binding>
197    ///   </object>
198    /// ```
199    ///
200    /// This is an Abstract Base Class, you cannot instantiate it.
201    #[doc(alias = "GtkExpression")]
202    pub struct Expression(Shared<ffi::GtkExpression>);
203
204    match fn {
205        ref => |ptr| ffi::gtk_expression_ref(ptr),
206        unref => |ptr| ffi::gtk_expression_unref(ptr),
207    }
208}
209
210impl StaticType for Expression {
211    fn static_type() -> glib::Type {
212        unsafe { from_glib(ffi::gtk_expression_get_type()) }
213    }
214}
215
216impl Expression {
217    pub const NONE: Option<&'static Expression> = None;
218
219    /// Bind `target`'s property named `property` to `self`.
220    ///
221    /// The value that `self` evaluates to is set via `g_object_set()` on
222    /// `target`. This is repeated whenever `self` changes to ensure that
223    /// the object's property stays synchronized with `self`.
224    ///
225    /// If `self`'s evaluation fails, `target`'s `property` is not updated.
226    /// Use a `Gtk::TryExpression` to provide a fallback for this case.
227    ///
228    /// Note that this function takes ownership of `self`. If you want
229    /// to keep it around, you should `Gtk::Expression::ref()` it beforehand.
230    /// ## `target`
231    /// the target object to bind to
232    /// ## `property`
233    /// name of the property on `target` to bind to
234    /// ## `this_`
235    /// the this argument for
236    ///   the evaluation of `self`
237    ///
238    /// # Returns
239    ///
240    /// a [`ExpressionWatch`][crate::ExpressionWatch]
241    #[doc(alias = "gtk_expression_bind")]
242    pub fn bind(
243        &self,
244        target: &impl IsA<glib::Object>,
245        property: &str,
246        this_: Option<&impl IsA<glib::Object>>,
247    ) -> ExpressionWatch {
248        unsafe {
249            from_glib_none(ffi::gtk_expression_bind(
250                self.as_ref().to_glib_full(),
251                target.as_ref().to_glib_none().0,
252                property.to_glib_none().0,
253                this_.map(|p| p.as_ref()).to_glib_none().0,
254            ))
255        }
256    }
257
258    /// Gets the `GType` that this expression evaluates to.
259    ///
260    /// This type is constant and will not change over the lifetime
261    /// of this expression.
262    ///
263    /// # Returns
264    ///
265    /// The type returned from [`evaluate()`][Self::evaluate()]
266    #[doc(alias = "gtk_expression_get_value_type")]
267    #[doc(alias = "get_value_type")]
268    pub fn value_type(&self) -> glib::types::Type {
269        unsafe {
270            from_glib(ffi::gtk_expression_get_value_type(
271                self.as_ref().to_glib_none().0,
272            ))
273        }
274    }
275
276    /// Checks if the expression is static.
277    ///
278    /// A static expression will never change its result when
279    /// [`evaluate()`][Self::evaluate()] is called on it with the same arguments.
280    ///
281    /// That means a call to [`watch()`][Self::watch()] is not necessary because
282    /// it will never trigger a notify.
283    ///
284    /// # Returns
285    ///
286    /// `TRUE` if the expression is static
287    #[doc(alias = "gtk_expression_is_static")]
288    pub fn is_static(&self) -> bool {
289        unsafe {
290            from_glib(ffi::gtk_expression_is_static(
291                self.as_ref().to_glib_none().0,
292            ))
293        }
294    }
295
296    /// Watch the given `expression` for changes.
297    ///
298    /// The @notify function will be called whenever the evaluation of `self`
299    /// may have changed.
300    ///
301    /// GTK cannot guarantee that the evaluation did indeed change when the @notify
302    /// gets invoked, but it guarantees the opposite: When it did in fact change,
303    /// the @notify will be invoked.
304    /// ## `this_`
305    /// the `this` argument to
306    ///   watch
307    /// ## `notify`
308    /// callback to invoke when the expression changes
309    ///
310    /// # Returns
311    ///
312    /// The newly installed watch. Note that the only
313    ///   reference held to the watch will be released when the watch is unwatched
314    ///   which can happen automatically, and not just via
315    ///   [`ExpressionWatch::unwatch()`][crate::ExpressionWatch::unwatch()]. You should call `Gtk::ExpressionWatch::ref()`
316    ///   if you want to keep the watch around.
317    #[doc(alias = "gtk_expression_watch")]
318    pub fn watch<P: Fn() + 'static>(
319        &self,
320        this_: Option<&impl IsA<glib::Object>>,
321        notify: P,
322    ) -> ExpressionWatch {
323        let notify_data: Box_<P> = Box_::new(notify);
324        unsafe extern "C" fn notify_func<P: Fn() + 'static>(user_data: glib::ffi::gpointer) {
325            unsafe {
326                let callback = &*(user_data as *mut P);
327                (*callback)()
328            }
329        }
330        let notify = Some(notify_func::<P> as _);
331        unsafe extern "C" fn user_destroy_func<P: Fn() + 'static>(data: glib::ffi::gpointer) {
332            unsafe {
333                let _callback = Box_::from_raw(data as *mut P);
334            }
335        }
336        let destroy_call4 = Some(user_destroy_func::<P> as _);
337        let super_callback0: Box_<P> = notify_data;
338        unsafe {
339            from_glib_none(ffi::gtk_expression_watch(
340                self.as_ref().to_glib_none().0,
341                this_.map(|p| p.as_ref()).to_glib_none().0,
342                notify,
343                Box_::into_raw(super_callback0) as *mut _,
344                destroy_call4,
345            ))
346        }
347    }
348}