slint_interpreter/
item_holder.rs1use crate::Value;
10use crate::erased::{ErasedItem, ErasedItemRc};
11use i_slint_core::Property;
12use i_slint_core::items::{ItemVTable, PropertyAnimation};
13use i_slint_core::rtti::{
14 AnimatedBindingKind, BuiltinItem, CallbackInfo, PropertyInfo, TwoWayBindingMapping,
15};
16use std::pin::Pin;
17use std::rc::Rc;
18use vtable::{HasStaticVTable, VRef};
19
20fn find_property<T: 'static + BuiltinItem>(
21 name: &str,
22) -> Option<&'static dyn PropertyInfo<T, Value>> {
23 T::properties::<Value>().into_iter().find_map(|(n, info)| (n == name).then_some(info))
24}
25
26fn find_callback<T: 'static + BuiltinItem>(
27 name: &str,
28) -> Option<&'static dyn CallbackInfo<T, Value>> {
29 T::callbacks::<Value>().into_iter().find_map(|(n, info)| (n == name).then_some(info))
30}
31
32impl<T> ErasedItem for T
33where
34 T: 'static + BuiltinItem + HasStaticVTable<ItemVTable>,
35{
36 fn get_property(self: Pin<&Self>, name: &str) -> Result<Value, ()> {
37 find_property::<T>(name).ok_or(())?.get(self)
38 }
39
40 fn set_property(
41 self: Pin<&Self>,
42 name: &str,
43 value: Value,
44 animation: Option<PropertyAnimation>,
45 ) -> Result<(), ()> {
46 find_property::<T>(name).ok_or(())?.set(self, value, animation)
47 }
48
49 fn set_property_binding(
50 self: Pin<&Self>,
51 name: &str,
52 binding: Box<dyn Fn() -> Value>,
53 animation: AnimatedBindingKind,
54 ) -> Result<(), ()> {
55 find_property::<T>(name).ok_or(())?.set_binding(self, binding, animation)
56 }
57
58 fn prepare_property_for_two_way_binding(
59 self: Pin<&Self>,
60 name: &str,
61 ) -> Option<Pin<Rc<Property<Value>>>> {
62 Some(find_property::<T>(name)?.prepare_for_two_way_binding(self))
63 }
64
65 fn link_property_two_way_with_map(
66 self: Pin<&Self>,
67 name: &str,
68 other: Pin<Rc<Property<Value>>>,
69 mapper: Option<Rc<dyn TwoWayBindingMapping<Value>>>,
70 ) {
71 if let Some(info) = find_property::<T>(name) {
72 info.link_two_way_with_map(self, other, mapper);
73 }
74 }
75
76 fn call_callback(self: Pin<&Self>, name: &str, args: &[Value]) -> Result<Value, ()> {
77 find_callback::<T>(name).ok_or(())?.call(self, args)
78 }
79
80 fn set_callback_handler(
81 self: Pin<&Self>,
82 name: &str,
83 handler: Box<dyn Fn(&[Value]) -> Value>,
84 ) -> Result<(), ()> {
85 find_callback::<T>(name).ok_or(())?.set_handler(self, handler)
86 }
87
88 fn set_field(self: Pin<&Self>, _name: &str, _value: Value) -> Result<(), ()> {
89 Err(())
93 }
94
95 fn as_item_ref(self: Pin<&Self>) -> Pin<VRef<'_, ItemVTable>> {
96 VRef::new_pin(self)
97 }
98}
99
100pub fn make_item<T>() -> ErasedItemRc
102where
103 T: 'static + Default + BuiltinItem + HasStaticVTable<ItemVTable>,
104{
105 Rc::pin(T::default())
106}