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}