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