slint_interpreter/
item_registry.rs1use crate::erased::ErasedItemRc;
11use crate::item_holder::make_item;
12use i_slint_core::items::*;
13use i_slint_core::rtti::BuiltinItem;
14use std::collections::HashMap;
15use std::sync::OnceLock;
16
17pub type ItemFactory = fn() -> ErasedItemRc;
18
19pub struct ItemRegistry {
20 factories: HashMap<&'static str, ItemFactory>,
21}
22
23impl ItemRegistry {
24 pub fn factory(&self, class_name: &str) -> Option<ItemFactory> {
25 self.factories.get(class_name).copied()
26 }
27
28 pub fn global() -> &'static ItemRegistry {
29 static REGISTRY: OnceLock<ItemRegistry> = OnceLock::new();
30 REGISTRY.get_or_init(ItemRegistry::build)
31 }
32
33 fn build() -> Self {
34 let mut factories: HashMap<&'static str, ItemFactory> = HashMap::new();
35
36 macro_rules! reg {
37 ($($ty:ident),* $(,)?) => {
38 $(
39 factories.insert(<$ty as BuiltinItem>::name(), make_item::<$ty> as ItemFactory);
40 )*
41 };
42 }
43
44 reg!(
45 ComponentContainer,
46 Empty,
47 ImageItem,
48 ClippedImage,
49 ComplexText,
50 StyledTextItem,
51 SimpleText,
52 Rectangle,
53 BasicBorderRectangle,
54 BorderRectangle,
55 TouchArea,
56 TooltipArea,
57 FocusScope,
58 KeyBinding,
59 SwipeGestureHandler,
60 ScaleRotateGestureHandler,
61 Path,
62 Flickable,
63 WindowItem,
64 TextInput,
65 Clip,
66 BoxShadow,
67 Transform,
68 Opacity,
69 Layer,
70 DragArea,
71 DropArea,
72 WindowMoveArea,
73 ContextMenu,
74 MenuItem,
75 SystemTrayIcon,
76 );
77
78 <i_slint_backend_selector::NativeWidgets as NativeHelper>::push(&mut factories);
80
81 ItemRegistry { factories }
82 }
83}
84
85trait NativeHelper {
87 fn push(factories: &mut HashMap<&'static str, ItemFactory>);
88}
89
90impl NativeHelper for () {
91 fn push(_: &mut HashMap<&'static str, ItemFactory>) {}
92}
93
94impl<T: 'static + Default + BuiltinItem + vtable::HasStaticVTable<ItemVTable>, Next: NativeHelper>
95 NativeHelper for (T, Next)
96{
97 fn push(factories: &mut HashMap<&'static str, ItemFactory>) {
98 factories.insert(<T as BuiltinItem>::name(), make_item::<T> as ItemFactory);
99 Next::push(factories);
100 }
101}