1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#pragma once
5
6#include "slint_internal.h"
7#include "slint_window.h"
8
9namespace slint {
10namespace private_api {
11// Bring opaque structure in scope
12using namespace cbindgen_private;
13using ItemTreeRef = vtable::VRef<private_api::ItemTreeVTable>;
14using IndexRange = cbindgen_private::IndexRange;
15using ItemRef = vtable::VRef<private_api::ItemVTable>;
16using ItemVisitorRefMut = vtable::VRefMut<cbindgen_private::ItemVisitorVTable>;
17using ItemTreeNode = cbindgen_private::ItemTreeNode;
18using ItemArrayEntry =
19 vtable::VOffset<uint8_t, slint::cbindgen_private::ItemVTable, vtable::AllowPin>;
20using ItemArray = slint::cbindgen_private::Slice<ItemArrayEntry>;
21
22constexpr inline ItemTreeNode make_item_node(uint32_t child_count, uint32_t child_index,
23 uint32_t parent_index, uint32_t item_array_index,
24 bool is_accessible)
25{
26 return ItemTreeNode { ItemTreeNode::Item_Body { .tag: ItemTreeNode::Tag::Item, .is_accessible: is_accessible,
27 .children_count: child_count, .children_index: child_index, .parent_index: parent_index,
28 .item_array_index: item_array_index } };
29}
30
31constexpr inline ItemTreeNode make_dyn_node(std::uint32_t offset, std::uint32_t parent_index)
32{
33 return ItemTreeNode { ItemTreeNode::DynamicTree_Body { .tag: ItemTreeNode::Tag::DynamicTree, .index: offset,
34 .parent_index: parent_index } };
35}
36
37inline ItemRef get_item_ref(ItemTreeRef item_tree,
38 const cbindgen_private::Slice<ItemTreeNode> item_tree_array,
39 const private_api::ItemArray item_array, int index)
40{
41 const auto item_array_index = item_tree_array.ptr[index].item.item_array_index;
42 const auto item = item_array[item_array_index];
43 return ItemRef { .vtable: item.vtable, .instance: reinterpret_cast<char *>(item_tree.instance) + item.offset };
44}
45
46} // namespace private_api
47
48template<typename T>
49class ComponentWeakHandle;
50
51/// The component handle is like a shared pointer to a component in the generated code.
52/// In order to get a component, use `T::create()` where T is the name of the component
53/// in the .slint file. This give you a `ComponentHandle<T>`
54template<typename T>
55class ComponentHandle
56{
57 vtable::VRc<private_api::ItemTreeVTable, T> inner;
58 friend class ComponentWeakHandle<T>;
59
60public:
61 /// internal constructor
62 ComponentHandle(const vtable::VRc<private_api::ItemTreeVTable, T> &inner) : inner(inner) { }
63
64 /// Arrow operator that implements pointer semantics.
65 const T *operator->() const
66 {
67 private_api::assert_main_thread();
68 return inner.operator->();
69 }
70 /// Dereference operator that implements pointer semantics.
71 const T &operator*() const
72 {
73 private_api::assert_main_thread();
74 return inner.operator*();
75 }
76 /// Arrow operator that implements pointer semantics.
77 T *operator->()
78 {
79 private_api::assert_main_thread();
80 return inner.operator->();
81 }
82 /// Dereference operator that implements pointer semantics.
83 T &operator*()
84 {
85 private_api::assert_main_thread();
86 return inner.operator*();
87 }
88
89 /// internal function that returns the internal handle
90 vtable::VRc<private_api::ItemTreeVTable> into_dyn() const { return inner.into_dyn(); }
91};
92
93/// A weak reference to the component. Can be constructed from a `ComponentHandle<T>`
94template<typename T>
95class ComponentWeakHandle
96{
97 vtable::VWeak<private_api::ItemTreeVTable, T> inner;
98
99public:
100 /// Constructs a null ComponentWeakHandle. lock() will always return empty.
101 ComponentWeakHandle() = default;
102 /// Copy-constructs a new ComponentWeakHandle from \a other.
103 ComponentWeakHandle(const ComponentHandle<T> &other) : inner(other.inner) { }
104 /// Returns a new strong ComponentHandle<T> if the component the weak handle points to is
105 /// still referenced by any other ComponentHandle<T>. An empty std::optional is returned
106 /// otherwise.
107 std::optional<ComponentHandle<T>> lock() const
108 {
109 private_api::assert_main_thread();
110 if (auto l = inner.lock()) {
111 return { ComponentHandle(*l) };
112 } else {
113 return {};
114 }
115 }
116};
117
118}
119

source code of slint/api/cpp/include/slint_item_tree.h