1use glib::{translate::*, value::FromValue, Object, Type, Value};
4
5use crate::{ffi, prelude::*, Expression};
6
7#[doc(hidden)]
8impl AsRef<Expression> for Expression {
9 #[inline]
10 fn as_ref(&self) -> &Expression {
11 self
12 }
13}
14
15pub unsafe trait IsExpression:
23 StaticType + FromGlibPtrFull<*mut ffi::GtkExpression> + 'static
24{
25}
26
27impl Expression {
28 #[inline]
29 pub fn upcast(self) -> Self {
30 self
31 }
32
33 #[inline]
34 pub fn upcast_ref(&self) -> &Self {
35 self
36 }
37
38 #[inline]
39 pub fn is<E: IsExpression>(&self) -> bool {
40 self.type_().is_a(E::static_type())
41 }
42
43 #[inline]
44 pub fn downcast<E: IsExpression>(self) -> Result<E, Expression> {
45 unsafe {
46 if self.is::<E>() {
47 Ok(from_glib_full(self.into_glib_ptr()))
48 } else {
49 Err(self)
50 }
51 }
52 }
53
54 #[inline]
55 pub fn downcast_ref<E: IsExpression>(&self) -> Option<&E> {
56 unsafe {
57 if self.is::<E>() {
58 Some(&*(self as *const Expression as *const E))
59 } else {
60 None
61 }
62 }
63 }
64
65 #[inline]
66 pub fn type_(&self) -> Type {
67 unsafe {
68 let ptr = self.as_ptr();
69 from_glib((*(*(ptr as *mut glib::gobject_ffi::GTypeInstance)).g_class).g_type)
70 }
71 }
72
73 #[doc(alias = "gtk_expression_evaluate")]
74 pub fn evaluate(&self, this: Option<&impl IsA<Object>>) -> Option<Value> {
75 assert_initialized_main_thread!();
76 unsafe {
77 let mut value = Value::uninitialized();
78 let ret = ffi::gtk_expression_evaluate(
79 self.to_glib_none().0,
80 this.map(|t| t.as_ref()).to_glib_none().0,
81 value.to_glib_none_mut().0,
82 );
83 if from_glib(ret) {
84 Some(value)
85 } else {
86 None
87 }
88 }
89 }
90
91 #[doc(alias = "gtk_expression_evaluate")]
95 pub fn evaluate_as<V: for<'b> FromValue<'b> + 'static, T: IsA<Object>>(
96 &self,
97 this: Option<&T>,
98 ) -> Option<V> {
99 self.evaluate(this).map(|v| {
100 v.get_owned::<V>()
101 .expect("Failed to evaluate to this value type")
102 })
103 }
104
105 pub fn chain_property<T: IsA<glib::Object>>(
110 &self,
111 property_name: &str,
112 ) -> crate::PropertyExpression {
113 crate::PropertyExpression::new(T::static_type(), Some(self), property_name)
114 }
115
116 pub fn chain_closure<R>(&self, closure: glib::RustClosure) -> crate::ClosureExpression
145 where
146 R: glib::value::ValueType,
147 {
148 crate::ClosureExpression::new::<R>([self], closure)
149 }
150
151 pub fn chain_closure_with_callback<F, R>(&self, f: F) -> crate::ClosureExpression
156 where
157 F: Fn(&[glib::Value]) -> R + 'static,
158 R: glib::value::ValueType,
159 {
160 crate::ClosureExpression::with_callback([self], f)
161 }
162}
163
164impl std::fmt::Debug for Expression {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 f.debug_struct("Expression")
167 .field("value_type", &self.value_type())
168 .field("is_static", &self.is_static())
169 .finish()
170 }
171}
172
173impl glib::value::ValueType for Expression {
174 type Type = Self;
175}
176
177unsafe impl<'a> glib::value::FromValue<'a> for Expression {
178 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
179
180 #[inline]
181 unsafe fn from_value(value: &'a glib::Value) -> Self {
182 skip_assert_initialized!();
183 from_glib_full(crate::ffi::gtk_value_dup_expression(value.to_glib_none().0))
184 }
185}
186
187impl glib::value::ToValue for Expression {
188 #[inline]
189 fn to_value(&self) -> glib::Value {
190 let mut value = glib::Value::for_value_type::<Self>();
191 unsafe {
192 crate::ffi::gtk_value_set_expression(value.to_glib_none_mut().0, self.to_glib_none().0)
193 }
194 value
195 }
196
197 #[inline]
198 fn value_type(&self) -> glib::Type {
199 Self::static_type()
200 }
201}
202
203impl glib::value::ToValueOptional for Expression {
204 fn to_value_optional(s: Option<&Self>) -> glib::Value {
205 skip_assert_initialized!();
206 let mut value = glib::Value::for_value_type::<Self>();
207 unsafe {
208 crate::ffi::gtk_value_set_expression(value.to_glib_none_mut().0, s.to_glib_none().0)
209 }
210 value
211 }
212}
213
214impl From<Expression> for glib::Value {
215 fn from(e: Expression) -> Self {
216 skip_assert_initialized!();
217 let mut value = glib::Value::for_value_type::<Expression>();
218 unsafe {
219 crate::ffi::gtk_value_take_expression(value.to_glib_none_mut().0, e.into_glib_ptr())
220 }
221 value
222 }
223}
224
225pub trait GObjectPropertyExpressionExt: IsA<glib::Object> {
245 fn property_expression(&self, property_name: &str) -> crate::PropertyExpression {
248 let obj_expr = crate::ConstantExpression::new(self);
249 crate::PropertyExpression::new(Self::static_type(), Some(&obj_expr), property_name)
250 }
251
252 fn property_expression_weak(&self, property_name: &str) -> crate::PropertyExpression {
256 let obj_expr = crate::ObjectExpression::new(self);
257 crate::PropertyExpression::new(Self::static_type(), Some(&obj_expr), property_name)
258 }
259
260 fn this_expression(property_name: &str) -> crate::PropertyExpression {
263 skip_assert_initialized!();
264 crate::PropertyExpression::new(Self::static_type(), Expression::NONE, property_name)
265 }
266}
267
268impl<O: IsA<glib::Object>> GObjectPropertyExpressionExt for O {}
269
270macro_rules! define_expression {
271 ($rust_type:ident, $ffi_type:path) => {
272 impl std::ops::Deref for $rust_type {
273 type Target = crate::Expression;
274
275 #[inline]
276 fn deref(&self) -> &Self::Target {
277 unsafe { &*(self as *const $rust_type as *const crate::Expression) }
278 }
279 }
280
281 impl AsRef<crate::Expression> for $rust_type {
282 #[inline]
283 fn as_ref(&self) -> &crate::Expression {
284 self.upcast_ref()
285 }
286 }
287
288 impl $rust_type {
289 #[inline]
290 pub fn upcast(self) -> crate::Expression {
291 unsafe { std::mem::transmute(self) }
292 }
293
294 #[inline]
295 pub fn upcast_ref(&self) -> &crate::Expression {
296 self
297 }
298 }
299
300 #[doc(hidden)]
301 impl<'a> ToGlibPtr<'a, *const crate::ffi::GtkExpression> for $rust_type {
302 type Storage =
303 ::std::marker::PhantomData<&'a $crate::glib::shared::Shared<$ffi_type, $rust_type>>;
304
305 #[inline]
306 fn to_glib_none(
307 &'a self,
308 ) -> $crate::glib::translate::Stash<'a, *const crate::ffi::GtkExpression, Self> {
309 let stash =
310 $crate::glib::translate::ToGlibPtr::<*const $ffi_type>::to_glib_none(self);
311 $crate::glib::translate::Stash(stash.0 as *const _, stash.1)
312 }
313
314 #[inline]
315 fn to_glib_full(&self) -> *const crate::ffi::GtkExpression {
316 $crate::glib::translate::ToGlibPtr::<*const $ffi_type>::to_glib_full(self)
317 as *const _
318 }
319 }
320
321 #[doc(hidden)]
322 impl<'a> ToGlibPtr<'a, *mut crate::ffi::GtkExpression> for $rust_type {
323 type Storage =
324 ::std::marker::PhantomData<&'a $crate::glib::shared::Shared<$ffi_type, $rust_type>>;
325
326 #[inline]
327 fn to_glib_none(
328 &'a self,
329 ) -> $crate::glib::translate::Stash<'a, *mut crate::ffi::GtkExpression, Self> {
330 let stash =
331 $crate::glib::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_none(self);
332 $crate::glib::translate::Stash(stash.0 as *mut _, stash.1)
333 }
334
335 #[inline]
336 fn to_glib_full(&self) -> *mut crate::ffi::GtkExpression {
337 $crate::glib::translate::ToGlibPtr::<*mut $ffi_type>::to_glib_full(self) as *mut _
338 }
339 }
340
341 #[doc(hidden)]
342 impl IntoGlibPtr<*mut crate::ffi::GtkExpression> for $rust_type {
343 #[inline]
344 unsafe fn into_glib_ptr(self) -> *mut crate::ffi::GtkExpression {
345 let s = std::mem::ManuallyDrop::new(self);
346 s.to_glib_none().0
347 }
348 }
349
350 #[doc(hidden)]
351 impl IntoGlibPtr<*const crate::ffi::GtkExpression> for $rust_type {
352 #[inline]
353 unsafe fn into_glib_ptr(self) -> *const crate::ffi::GtkExpression {
354 let s = std::mem::ManuallyDrop::new(self);
355 s.to_glib_none().0
356 }
357 }
358
359 #[doc(hidden)]
360 impl FromGlibPtrFull<*mut crate::ffi::GtkExpression> for $rust_type {
361 #[inline]
362 unsafe fn from_glib_full(ptr: *mut crate::ffi::GtkExpression) -> Self {
363 from_glib_full(ptr as *mut $ffi_type)
364 }
365 }
366
367 unsafe impl crate::expression::IsExpression for $rust_type {}
368
369 impl glib::value::ValueType for $rust_type {
370 type Type = Self;
371 }
372
373 unsafe impl<'a> glib::value::FromValue<'a> for $rust_type {
374 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
375
376 #[inline]
377 unsafe fn from_value(value: &'a glib::Value) -> Self {
378 skip_assert_initialized!();
379 from_glib_full(crate::ffi::gtk_value_dup_expression(value.to_glib_none().0))
380 }
381 }
382
383 impl glib::value::ToValue for $rust_type {
384 #[inline]
385 fn to_value(&self) -> glib::Value {
386 let mut value = glib::Value::for_value_type::<Self>();
387 unsafe {
388 crate::ffi::gtk_value_set_expression(
389 value.to_glib_none_mut().0,
390 self.as_ptr() as *mut _,
391 )
392 }
393 value
394 }
395
396 #[inline]
397 fn value_type(&self) -> glib::Type {
398 use glib::prelude::StaticType;
399 Self::static_type()
400 }
401 }
402
403 impl glib::value::ToValueOptional for $rust_type {
404 #[inline]
405 fn to_value_optional(s: Option<&Self>) -> glib::Value {
406 skip_assert_initialized!();
407 let mut value = glib::Value::for_value_type::<Self>();
408 unsafe {
409 crate::ffi::gtk_value_set_expression(
410 value.to_glib_none_mut().0,
411 s.map(|s| s.as_ptr()).unwrap_or(std::ptr::null_mut()) as *mut _,
412 )
413 }
414 value
415 }
416 }
417
418 impl From<$rust_type> for glib::Value {
419 fn from(e: $rust_type) -> Self {
420 skip_assert_initialized!();
421 let mut value = glib::Value::for_value_type::<$rust_type>();
422 unsafe {
423 crate::ffi::gtk_value_take_expression(
424 value.to_glib_none_mut().0,
425 e.into_glib_ptr(),
426 )
427 }
428 value
429 }
430 }
431
432 impl glib::HasParamSpec for $rust_type {
433 type ParamSpec = crate::ParamSpecExpression;
434
435 type SetValue = $rust_type;
436
437 type BuilderFn = for<'a> fn(&'a str) -> crate::builders::ParamSpecExpressionBuilder<'a>;
438
439 fn param_spec_builder() -> Self::BuilderFn {
440 Self::ParamSpec::builder
441 }
442 }
443 };
444}