mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
Add item_tree function to Component VTable
This commit is contained in:
parent
106593eddc
commit
ea684fa4de
4 changed files with 56 additions and 15 deletions
|
@ -861,7 +861,7 @@ fn generate_item_tree(
|
|||
visit_children_statements.extend([
|
||||
"};".into(),
|
||||
format!("auto self_rc = reinterpret_cast<const {}*>(component.instance)->self_weak.lock()->into_dyn();", item_tree_class_name),
|
||||
"return slint::cbindgen_private::slint_visit_item_tree(&self_rc, item_tree() , index, order, visitor, dyn_visit);".to_owned(),
|
||||
"return slint::cbindgen_private::slint_visit_item_tree(&self_rc, get_item_tree(component) , index, order, visitor, dyn_visit);".to_owned(),
|
||||
]);
|
||||
|
||||
target_struct.members.push((
|
||||
|
@ -874,6 +874,7 @@ fn generate_item_tree(
|
|||
..Default::default()
|
||||
}),
|
||||
));
|
||||
|
||||
target_struct.members.push((
|
||||
Access::Private,
|
||||
Declaration::Function(Function {
|
||||
|
@ -881,7 +882,20 @@ fn generate_item_tree(
|
|||
signature: "(slint::private_api::ComponentRef component, uintptr_t index) -> slint::private_api::ItemRef".into(),
|
||||
is_static: true,
|
||||
statements: Some(vec![
|
||||
"return slint::private_api::get_item_ref(component, item_tree(), item_array(), index);".to_owned(),
|
||||
"return slint::private_api::get_item_ref(component, get_item_tree(component), item_array(), index);".to_owned(),
|
||||
]),
|
||||
..Default::default()
|
||||
}),
|
||||
));
|
||||
|
||||
target_struct.members.push((
|
||||
Access::Private,
|
||||
Declaration::Function(Function {
|
||||
name: "get_item_tree".into(),
|
||||
signature: "(slint::private_api::ComponentRef) -> slint::cbindgen_private::Slice<slint::private_api::ItemTreeNode>".into(),
|
||||
is_static: true,
|
||||
statements: Some(vec![
|
||||
"return item_tree();".to_owned(),
|
||||
]),
|
||||
..Default::default()
|
||||
}),
|
||||
|
@ -895,7 +909,7 @@ fn generate_item_tree(
|
|||
}) {
|
||||
format!(
|
||||
// that does not work when the parent is not a component with a ComponentVTable
|
||||
//" *result = slint::private_api::parent_item(self->parent->self_weak.into_dyn(), self->parent->item_tree(), {});",
|
||||
//" *result = slint::private_api::parent_item(self->parent->self_weak.into_dyn(), self->parent->get_item_tree(), {});",
|
||||
"self->parent->self_weak.vtable()->parent_item(self->parent->self_weak.lock()->borrow(), {}, result);",
|
||||
parent_index,
|
||||
)
|
||||
|
@ -914,7 +928,7 @@ fn generate_item_tree(
|
|||
parent_item_from_parent_component,
|
||||
" return;".into(),
|
||||
"}".into(),
|
||||
"*result = slint::private_api::parent_item(self->self_weak.into_dyn(), item_tree(), index);".into(),
|
||||
"*result = slint::private_api::parent_item(self->self_weak.into_dyn(), get_item_tree(component), index);".into(),
|
||||
]),
|
||||
..Default::default()
|
||||
}),
|
||||
|
@ -981,7 +995,7 @@ fn generate_item_tree(
|
|||
ty: "const slint::private_api::ComponentVTable".to_owned(),
|
||||
name: format!("{}::static_vtable", item_tree_class_name),
|
||||
init: Some(format!(
|
||||
"{{ visit_children, get_item_ref, parent_item, layout_info, slint::private_api::drop_in_place<{}>, slint::private_api::dealloc }}",
|
||||
"{{ visit_children, get_item_ref, get_item_tree, parent_item, layout_info, slint::private_api::drop_in_place<{}>, slint::private_api::dealloc }}",
|
||||
item_tree_class_name)
|
||||
),
|
||||
..Default::default()
|
||||
|
|
|
@ -1058,7 +1058,7 @@ fn generate_item_tree(
|
|||
-> slint::re_exports::VisitChildrenResult
|
||||
{
|
||||
use slint::re_exports::*;
|
||||
return slint::re_exports::visit_item_tree(self, &VRcMapped::origin(&self.as_ref().self_weak.get().unwrap().upgrade().unwrap()), Self::item_tree(), index, order, visitor, visit_dynamic);
|
||||
return slint::re_exports::visit_item_tree(self, &VRcMapped::origin(&self.as_ref().self_weak.get().unwrap().upgrade().unwrap()), self.get_item_tree().as_slice(), index, order, visitor, visit_dynamic);
|
||||
#[allow(unused)]
|
||||
fn visit_dynamic(_self: ::core::pin::Pin<&#inner_component_id>, order: slint::re_exports::TraversalOrder, visitor: ItemVisitorRefMut, dyn_index: usize) -> VisitChildrenResult {
|
||||
_self.visit_dynamic_children(dyn_index, order, visitor)
|
||||
|
@ -1066,7 +1066,7 @@ fn generate_item_tree(
|
|||
}
|
||||
|
||||
fn get_item_ref(self: ::core::pin::Pin<&Self>, index: usize) -> ::core::pin::Pin<ItemRef> {
|
||||
match &Self::item_tree()[index] {
|
||||
match &self.get_item_tree().as_slice()[index] {
|
||||
ItemTreeNode::Item { item_array_index, .. } => {
|
||||
Self::item_array()[*item_array_index as usize].apply_pin(self)
|
||||
}
|
||||
|
@ -1075,6 +1075,12 @@ fn generate_item_tree(
|
|||
}
|
||||
}
|
||||
|
||||
fn get_item_tree(
|
||||
self: ::core::pin::Pin<&Self>) -> slint::re_exports::Slice<slint::re_exports::ItemTreeNode>
|
||||
{
|
||||
Self::item_tree().into()
|
||||
}
|
||||
|
||||
fn parent_item(self: ::core::pin::Pin<&Self>, index: usize, result: &mut slint::re_exports::ItemWeak) {
|
||||
if index == 0 {
|
||||
#(
|
||||
|
@ -1084,7 +1090,7 @@ fn generate_item_tree(
|
|||
)*
|
||||
return;
|
||||
}
|
||||
let parent_index = Self::item_tree()[index].parent_index();
|
||||
let parent_index = self.get_item_tree().as_slice()[index].parent_index();
|
||||
let self_rc = slint::re_exports::VRcMapped::origin(&self.self_weak.get().unwrap().upgrade().unwrap());
|
||||
*result = ItemRc::new(self_rc, parent_index).downgrade();
|
||||
}
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
|
||||
//! This module contains the basic datastructures that are exposed to the C API
|
||||
|
||||
use crate::item_tree::{ItemVisitorVTable, TraversalOrder, VisitChildrenResult};
|
||||
use crate::item_tree::{ItemTreeNode, ItemVisitorVTable, TraversalOrder, VisitChildrenResult};
|
||||
use crate::items::{ItemVTable, ItemWeak};
|
||||
use crate::layout::{LayoutInfo, Orientation};
|
||||
use crate::slice::Slice;
|
||||
use crate::window::WindowRc;
|
||||
use vtable::*;
|
||||
|
||||
|
@ -31,6 +32,11 @@ pub struct ComponentVTable {
|
|||
index: usize,
|
||||
) -> core::pin::Pin<VRef<ItemVTable>>,
|
||||
|
||||
/// Return the item tree that is defined by this `Component`.
|
||||
/// The return value is an item weak because it can be null if there is no parent.
|
||||
/// And the return value is passed by &mut because ItemWeak has a destructor
|
||||
pub get_item_tree: extern "C" fn(core::pin::Pin<VRef<ComponentVTable>>) -> Slice<ItemTreeNode>,
|
||||
|
||||
/// Return the parent item.
|
||||
/// The return value is an item weak because it can be null if there is no parent.
|
||||
/// And the return value is passed by &mut because ItemWeak has a destructor
|
||||
|
@ -82,7 +88,6 @@ pub(crate) mod ffi {
|
|||
#![allow(unsafe_code)]
|
||||
|
||||
use super::*;
|
||||
use crate::slice::Slice;
|
||||
|
||||
/// Call init() on the ItemVTable of each item in the item array.
|
||||
#[no_mangle]
|
||||
|
|
|
@ -22,6 +22,7 @@ use i_slint_core::model::RepeatedComponent;
|
|||
use i_slint_core::model::Repeater;
|
||||
use i_slint_core::properties::InterpolatedPropertyValue;
|
||||
use i_slint_core::rtti::{self, AnimatedBindingKind, FieldOffset, PropertyInfo};
|
||||
use i_slint_core::slice::Slice;
|
||||
use i_slint_core::window::{WindowHandleAccess, WindowRc};
|
||||
use i_slint_core::{Brush, Color, Property, SharedString, SharedVector};
|
||||
use std::collections::BTreeMap;
|
||||
|
@ -161,12 +162,18 @@ impl Component for ErasedComponentBox {
|
|||
fn layout_info(self: Pin<&Self>, orientation: Orientation) -> i_slint_core::layout::LayoutInfo {
|
||||
self.borrow().as_ref().layout_info(orientation)
|
||||
}
|
||||
|
||||
fn get_item_tree(self: Pin<&Self>) -> Slice<ItemTreeNode> {
|
||||
get_item_tree(self.get_ref().borrow())
|
||||
}
|
||||
|
||||
fn get_item_ref(self: Pin<&Self>, index: usize) -> Pin<ItemRef> {
|
||||
// We're having difficulties transferring the lifetime to a pinned reference
|
||||
// to the other ComponentVTable with the same life time. So skip the vtable
|
||||
// indirection and call our implementation directly.
|
||||
unsafe { get_item_ref(self.get_ref().borrow(), index) }
|
||||
}
|
||||
|
||||
fn parent_item(self: Pin<&Self>, index: usize, result: &mut ItemWeak) {
|
||||
self.borrow().as_ref().parent_item(index, result)
|
||||
}
|
||||
|
@ -582,7 +589,7 @@ extern "C" fn visit_children_item(
|
|||
i_slint_core::item_tree::visit_item_tree(
|
||||
instance_ref.instance,
|
||||
&vtable::VRc::into_dyn(comp_rc),
|
||||
instance_ref.component_type.item_tree.as_slice(),
|
||||
get_item_tree(component).as_slice(),
|
||||
index,
|
||||
order,
|
||||
v,
|
||||
|
@ -1021,6 +1028,7 @@ pub(crate) fn generate_component<'id>(
|
|||
visit_children_item,
|
||||
layout_info,
|
||||
get_item_ref,
|
||||
get_item_tree,
|
||||
parent_item,
|
||||
drop_in_place,
|
||||
dealloc,
|
||||
|
@ -1495,10 +1503,11 @@ extern "C" fn layout_info(component: ComponentRefPin, orientation: Orientation)
|
|||
}
|
||||
|
||||
unsafe extern "C" fn get_item_ref(component: ComponentRefPin, index: usize) -> Pin<ItemRef> {
|
||||
generativity::make_guard!(guard);
|
||||
let instance_ref = InstanceRef::from_pin_ref(component, guard);
|
||||
match &instance_ref.component_type.item_tree.as_slice()[index] {
|
||||
let tree = get_item_tree(component);
|
||||
match &tree[index] {
|
||||
ItemTreeNode::Item { item_array_index, .. } => {
|
||||
generativity::make_guard!(guard);
|
||||
let instance_ref = InstanceRef::from_pin_ref(component, guard);
|
||||
core::mem::transmute::<Pin<ItemRef>, Pin<ItemRef>>(
|
||||
instance_ref.component_type.item_array[*item_array_index as usize]
|
||||
.apply_pin(instance_ref.instance),
|
||||
|
@ -1508,6 +1517,13 @@ unsafe extern "C" fn get_item_ref(component: ComponentRefPin, index: usize) -> P
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" fn get_item_tree(component: ComponentRefPin) -> Slice<ItemTreeNode> {
|
||||
generativity::make_guard!(guard);
|
||||
let instance_ref = unsafe { InstanceRef::from_pin_ref(component, guard) };
|
||||
let tree = instance_ref.component_type.item_tree.as_slice();
|
||||
unsafe { core::mem::transmute::<&[ItemTreeNode], &[ItemTreeNode]>(tree) }.into()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize, result: &mut ItemWeak) {
|
||||
generativity::make_guard!(guard);
|
||||
let instance_ref = InstanceRef::from_pin_ref(component, guard);
|
||||
|
@ -1537,7 +1553,7 @@ unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize, resul
|
|||
}
|
||||
return;
|
||||
}
|
||||
let parent_index = instance_ref.component_type.item_tree.as_slice()[index].parent_index();
|
||||
let parent_index = get_item_tree(component)[index].parent_index();
|
||||
let self_rc = instance_ref.self_weak().get().unwrap().clone().into_dyn().upgrade().unwrap();
|
||||
*result = ItemRc::new(self_rc, parent_index).downgrade();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue