mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 14:51:15 +00:00
Visit the item as Pin
A preparation to have Property::get to take Pin<Self>
This commit is contained in:
parent
40f4265071
commit
1b748792ad
8 changed files with 86 additions and 48 deletions
|
@ -472,6 +472,18 @@ impl<Base, T: ?Sized + VTableMeta, Flag> VOffset<Base, T, Flag> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Base, T: ?Sized + VTableMeta> VOffset<Base, T, PinnedFlag> {
|
||||
pub fn apply_pin<'a>(self, x: Pin<&'a Base>) -> Pin<VRef<'a, T>> {
|
||||
let ptr = x.get_ref() as *const Base as *mut u8;
|
||||
unsafe {
|
||||
Pin::new_unchecked(VRef::from_raw(
|
||||
NonNull::from(self.vtable),
|
||||
NonNull::new_unchecked(ptr.add(self.offset)),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to implement manually otheriwse it is not implemented if T do not implement Copy / Clone
|
||||
impl<Base, T: ?Sized + VTableMeta, Flag> Copy for VOffset<Base, T, Flag> {}
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ pub fn generate(component: &Rc<Component>, diag: &mut Diagnostics) -> Option<Tok
|
|||
#(#repeated_element_names : sixtyfps::re_exports::Repeater<#repeated_element_components>,)*
|
||||
}
|
||||
|
||||
impl core::default::Default for #component_id {
|
||||
impl ::core::default::Default for #component_id {
|
||||
fn default() -> Self {
|
||||
#![allow(unused)]
|
||||
use sixtyfps::re_exports::*;
|
||||
|
@ -294,12 +294,12 @@ pub fn generate(component: &Rc<Component>, diag: &mut Diagnostics) -> Option<Tok
|
|||
|
||||
}
|
||||
impl sixtyfps::re_exports::Component for #component_id {
|
||||
fn visit_children_item(self: core::pin::Pin<&Self>, index: isize, visitor: sixtyfps::re_exports::ItemVisitorRefMut) {
|
||||
fn visit_children_item(self: ::core::pin::Pin<&Self>, index: isize, visitor: sixtyfps::re_exports::ItemVisitorRefMut) {
|
||||
use sixtyfps::re_exports::*;
|
||||
let tree = &[#(#item_tree_array),*];
|
||||
sixtyfps::re_exports::visit_item_tree(self.get_ref(), VRef::new_pin(self), tree, index, visitor, visit_dynamic);
|
||||
sixtyfps::re_exports::visit_item_tree(self, VRef::new_pin(self), tree, index, visitor, visit_dynamic);
|
||||
#[allow(unused)]
|
||||
fn visit_dynamic(base: &#component_id, visitor: ItemVisitorRefMut, dyn_index: usize) {
|
||||
fn visit_dynamic(base: ::core::pin::Pin<&#component_id>, visitor: ItemVisitorRefMut, dyn_index: usize) {
|
||||
match dyn_index {
|
||||
#(#repeated_visit_branch)*
|
||||
_ => panic!("invalid dyn_index {}", dyn_index),
|
||||
|
@ -604,10 +604,10 @@ fn compute_layout(component: &Component) -> TokenStream {
|
|||
}
|
||||
|
||||
quote! {
|
||||
fn layout_info(self: core::pin::Pin<&Self>) -> sixtyfps::re_exports::LayoutInfo {
|
||||
fn layout_info(self: ::core::pin::Pin<&Self>) -> sixtyfps::re_exports::LayoutInfo {
|
||||
todo!("Implement in rust.rs")
|
||||
}
|
||||
fn compute_layout(self: core::pin::Pin<&Self>, eval_context: &sixtyfps::re_exports::EvaluationContext) {
|
||||
fn compute_layout(self: ::core::pin::Pin<&Self>, eval_context: &sixtyfps::re_exports::EvaluationContext) {
|
||||
#![allow(unused)]
|
||||
use sixtyfps::re_exports::*;
|
||||
let dummy = Property::<f32>::default();
|
||||
|
|
|
@ -106,7 +106,8 @@ pub enum ItemTreeNode<T> {
|
|||
#[repr(C)]
|
||||
pub struct ItemVTable {
|
||||
/// Returns the geometry of this item (relative to its parent item)
|
||||
pub geometry: extern "C" fn(VRef<'_, ItemVTable>, context: &crate::EvaluationContext) -> Rect,
|
||||
pub geometry:
|
||||
extern "C" fn(core::pin::Pin<VRef<ItemVTable>>, context: &crate::EvaluationContext) -> Rect,
|
||||
|
||||
/// offset in bytes fromthe *const ItemImpl.
|
||||
/// isize::MAX means None
|
||||
|
@ -116,15 +117,16 @@ pub struct ItemVTable {
|
|||
|
||||
/// Return the rendering primitive used to display this item.
|
||||
pub rendering_primitive: extern "C" fn(
|
||||
VRef<'_, ItemVTable>,
|
||||
core::pin::Pin<VRef<ItemVTable>>,
|
||||
context: &crate::EvaluationContext,
|
||||
) -> RenderingPrimitive,
|
||||
|
||||
/// We would need max/min/preferred size, and all layout info
|
||||
pub layouting_info: extern "C" fn(VRef<'_, ItemVTable>) -> LayoutInfo,
|
||||
pub layouting_info: extern "C" fn(core::pin::Pin<VRef<ItemVTable>>) -> LayoutInfo,
|
||||
|
||||
/// input event
|
||||
pub input_event: extern "C" fn(VRef<'_, ItemVTable>, MouseEvent, &crate::EvaluationContext),
|
||||
pub input_event:
|
||||
extern "C" fn(core::pin::Pin<VRef<ItemVTable>>, MouseEvent, &crate::EvaluationContext),
|
||||
}
|
||||
|
||||
/// The constraint that applies to an item
|
||||
|
@ -328,19 +330,14 @@ pub struct ItemVisitorVTable {
|
|||
VRefMut<ItemVisitorVTable>,
|
||||
component: Pin<VRef<ComponentVTable>>,
|
||||
index: isize,
|
||||
item: VRef<ItemVTable>,
|
||||
item: Pin<VRef<ItemVTable>>,
|
||||
),
|
||||
/// Destructor
|
||||
drop: fn(VRefMut<ItemVisitorVTable>),
|
||||
}
|
||||
|
||||
impl<T: FnMut(crate::ComponentRefPin, isize, VRef<ItemVTable>)> ItemVisitor for T {
|
||||
fn visit_item(
|
||||
&mut self,
|
||||
component: crate::ComponentRefPin,
|
||||
index: isize,
|
||||
item: VRef<ItemVTable>,
|
||||
) {
|
||||
impl<T: FnMut(crate::ComponentRefPin, isize, Pin<ItemRef>)> ItemVisitor for T {
|
||||
fn visit_item(&mut self, component: crate::ComponentRefPin, index: isize, item: Pin<ItemRef>) {
|
||||
self(component, index, item)
|
||||
}
|
||||
}
|
||||
|
@ -361,12 +358,12 @@ pub unsafe extern "C" fn sixtyfps_visit_item_tree(
|
|||
),
|
||||
) {
|
||||
crate::item_tree::visit_item_tree(
|
||||
&*(component.as_ptr() as *const u8),
|
||||
Pin::new_unchecked(&*(component.as_ptr() as *const u8)),
|
||||
component,
|
||||
item_tree.as_slice(),
|
||||
index,
|
||||
visitor,
|
||||
|a, b, c| visit_dynamic(a, b, c),
|
||||
|a, b, c| visit_dynamic(a.get_ref(), b, c),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ use super::datastructures::{
|
|||
use crate::rtti::*;
|
||||
use crate::{EvaluationContext, Property, SharedString, Signal};
|
||||
use const_field_offset::FieldOffsets;
|
||||
use core::pin::Pin;
|
||||
use corelib_macro::*;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -39,7 +40,7 @@ pub struct Rectangle {
|
|||
}
|
||||
|
||||
impl Item for Rectangle {
|
||||
fn geometry(&self, context: &EvaluationContext) -> Rect {
|
||||
fn geometry(self: Pin<&Self>, context: &EvaluationContext) -> Rect {
|
||||
euclid::rect(
|
||||
self.x.get(context),
|
||||
self.y.get(context),
|
||||
|
@ -47,7 +48,10 @@ impl Item for Rectangle {
|
|||
self.height.get(context),
|
||||
)
|
||||
}
|
||||
fn rendering_primitive(&self, context: &crate::EvaluationContext) -> RenderingPrimitive {
|
||||
fn rendering_primitive(
|
||||
self: Pin<&Self>,
|
||||
context: &crate::EvaluationContext,
|
||||
) -> RenderingPrimitive {
|
||||
let width = self.width.get(context);
|
||||
let height = self.height.get(context);
|
||||
if width > 0. && height > 0. {
|
||||
|
@ -63,11 +67,16 @@ impl Item for Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
fn layouting_info(&self) -> LayoutInfo {
|
||||
fn layouting_info(self: Pin<&Self>) -> LayoutInfo {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn input_event(&self, _: super::datastructures::MouseEvent, _: &crate::EvaluationContext) {}
|
||||
fn input_event(
|
||||
self: Pin<&Self>,
|
||||
_: super::datastructures::MouseEvent,
|
||||
_: &crate::EvaluationContext,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemConsts for Rectangle {
|
||||
|
@ -93,7 +102,7 @@ pub struct Image {
|
|||
}
|
||||
|
||||
impl Item for Image {
|
||||
fn geometry(&self, context: &crate::EvaluationContext) -> Rect {
|
||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||
euclid::rect(
|
||||
self.x.get(context),
|
||||
self.y.get(context),
|
||||
|
@ -101,7 +110,10 @@ impl Item for Image {
|
|||
self.height.get(context),
|
||||
)
|
||||
}
|
||||
fn rendering_primitive(&self, context: &crate::EvaluationContext) -> RenderingPrimitive {
|
||||
fn rendering_primitive(
|
||||
self: Pin<&Self>,
|
||||
context: &crate::EvaluationContext,
|
||||
) -> RenderingPrimitive {
|
||||
RenderingPrimitive::Image {
|
||||
x: self.x.get(context),
|
||||
y: self.y.get(context),
|
||||
|
@ -109,12 +121,17 @@ impl Item for Image {
|
|||
}
|
||||
}
|
||||
|
||||
fn layouting_info(&self) -> LayoutInfo {
|
||||
fn layouting_info(self: Pin<&Self>) -> LayoutInfo {
|
||||
// FIXME: should we use the image size here
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn input_event(&self, _: super::datastructures::MouseEvent, _: &crate::EvaluationContext) {}
|
||||
fn input_event(
|
||||
self: Pin<&Self>,
|
||||
_: super::datastructures::MouseEvent,
|
||||
_: &crate::EvaluationContext,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemConsts for Image {
|
||||
|
@ -142,10 +159,13 @@ pub struct Text {
|
|||
|
||||
impl Item for Text {
|
||||
// FIXME: width / height. or maybe it doesn't matter? (
|
||||
fn geometry(&self, context: &crate::EvaluationContext) -> Rect {
|
||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||
euclid::rect(self.x.get(context), self.y.get(context), 0., 0.)
|
||||
}
|
||||
fn rendering_primitive(&self, context: &crate::EvaluationContext) -> RenderingPrimitive {
|
||||
fn rendering_primitive(
|
||||
self: Pin<&Self>,
|
||||
context: &crate::EvaluationContext,
|
||||
) -> RenderingPrimitive {
|
||||
RenderingPrimitive::Text {
|
||||
x: self.x.get(context),
|
||||
y: self.y.get(context),
|
||||
|
@ -156,11 +176,16 @@ impl Item for Text {
|
|||
}
|
||||
}
|
||||
|
||||
fn layouting_info(&self) -> LayoutInfo {
|
||||
fn layouting_info(self: Pin<&Self>) -> LayoutInfo {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn input_event(&self, _: super::datastructures::MouseEvent, _: &crate::EvaluationContext) {}
|
||||
fn input_event(
|
||||
self: Pin<&Self>,
|
||||
_: super::datastructures::MouseEvent,
|
||||
_: &crate::EvaluationContext,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemConsts for Text {
|
||||
|
@ -187,7 +212,7 @@ pub struct TouchArea {
|
|||
}
|
||||
|
||||
impl Item for TouchArea {
|
||||
fn geometry(&self, context: &crate::EvaluationContext) -> Rect {
|
||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||
euclid::rect(
|
||||
self.x.get(context),
|
||||
self.y.get(context),
|
||||
|
@ -195,16 +220,19 @@ impl Item for TouchArea {
|
|||
self.height.get(context),
|
||||
)
|
||||
}
|
||||
fn rendering_primitive(&self, _context: &crate::EvaluationContext) -> RenderingPrimitive {
|
||||
fn rendering_primitive(
|
||||
self: Pin<&Self>,
|
||||
_context: &crate::EvaluationContext,
|
||||
) -> RenderingPrimitive {
|
||||
RenderingPrimitive::NoContents
|
||||
}
|
||||
|
||||
fn layouting_info(&self) -> LayoutInfo {
|
||||
fn layouting_info(self: Pin<&Self>) -> LayoutInfo {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn input_event(
|
||||
&self,
|
||||
self: Pin<&Self>,
|
||||
event: super::datastructures::MouseEvent,
|
||||
context: &crate::EvaluationContext,
|
||||
) {
|
||||
|
|
|
@ -13,13 +13,13 @@ pub fn process_mouse_event(component: ComponentRefPin, event: MouseEvent) {
|
|||
crate::item_tree::visit_items(
|
||||
component,
|
||||
|context, item, offset| {
|
||||
let geom = item.geometry(context);
|
||||
let geom = item.as_ref().geometry(context);
|
||||
let geom = geom.translate(*offset);
|
||||
|
||||
if geom.contains(event.pos) {
|
||||
let mut event2 = event.clone();
|
||||
event2.pos -= geom.origin.to_vector();
|
||||
item.input_event(event2, context);
|
||||
item.as_ref().input_event(event2, context);
|
||||
}
|
||||
|
||||
geom.origin.to_vector()
|
||||
|
|
|
@ -7,11 +7,11 @@ use cgmath::{Matrix4, SquareMatrix, Vector3};
|
|||
|
||||
pub(crate) fn update_item_rendering_data<Backend: GraphicsBackend>(
|
||||
context: &EvaluationContext,
|
||||
item: ItemRef<'_>,
|
||||
item: core::pin::Pin<ItemRef>,
|
||||
rendering_cache: &mut RenderingCache<Backend>,
|
||||
rendering_primitives_builder: &mut Backend::RenderingPrimitivesBuilder,
|
||||
) {
|
||||
let item_rendering_primitive = item.rendering_primitive(context);
|
||||
let item_rendering_primitive = item.as_ref().rendering_primitive(context);
|
||||
|
||||
let rendering_data = item.cached_rendering_data_offset();
|
||||
|
||||
|
@ -47,7 +47,7 @@ pub(crate) fn render_component_items<Backend: GraphicsBackend>(
|
|||
crate::item_tree::visit_items(
|
||||
component,
|
||||
|context, item, transform| {
|
||||
let origin = item.geometry(context).origin;
|
||||
let origin = item.as_ref().geometry(context).origin;
|
||||
let transform =
|
||||
transform * Matrix4::from_translation(Vector3::new(origin.x, origin.y, 0.));
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::abi::datastructures::{ItemRef, ItemTreeNode, ItemVisitor, ItemVisitorVTable};
|
||||
use crate::ComponentRefPin;
|
||||
use crate::EvaluationContext;
|
||||
use core::pin::Pin;
|
||||
|
||||
/// Visit each items recursively
|
||||
///
|
||||
/// The state parametter returned by the visitor is passed to each children.
|
||||
pub fn visit_items<State>(
|
||||
component: ComponentRefPin,
|
||||
mut visitor: impl FnMut(&EvaluationContext, ItemRef, &State) -> State,
|
||||
mut visitor: impl FnMut(&EvaluationContext, Pin<ItemRef>, &State) -> State,
|
||||
state: State,
|
||||
) {
|
||||
let context = EvaluationContext::for_root_component(component);
|
||||
|
@ -16,11 +17,11 @@ pub fn visit_items<State>(
|
|||
|
||||
fn visit_internal<State>(
|
||||
context: &EvaluationContext,
|
||||
visitor: &mut impl FnMut(&EvaluationContext, ItemRef, &State) -> State,
|
||||
visitor: &mut impl FnMut(&EvaluationContext, Pin<ItemRef>, &State) -> State,
|
||||
index: isize,
|
||||
state: &State,
|
||||
) {
|
||||
let mut actual_visitor = |component: ComponentRefPin, index: isize, item: ItemRef| {
|
||||
let mut actual_visitor = |component: ComponentRefPin, index: isize, item: Pin<ItemRef>| {
|
||||
if component.as_ptr() == context.component.as_ptr() {
|
||||
let s = visitor(context, item, state);
|
||||
visit_internal(context, visitor, index, &s);
|
||||
|
@ -43,16 +44,16 @@ fn visit_internal<State>(
|
|||
/// Need to check if the compiler is able to optimize away some of it.
|
||||
/// Possibly we should generate code that directly call the visitor instead
|
||||
pub fn visit_item_tree<Base>(
|
||||
base: &Base,
|
||||
base: Pin<&Base>,
|
||||
component: ComponentRefPin,
|
||||
item_tree: &[ItemTreeNode<Base>],
|
||||
index: isize,
|
||||
mut visitor: vtable::VRefMut<ItemVisitorVTable>,
|
||||
visit_dynamic: impl Fn(&Base, vtable::VRefMut<ItemVisitorVTable>, usize),
|
||||
visit_dynamic: impl Fn(Pin<&Base>, vtable::VRefMut<ItemVisitorVTable>, usize),
|
||||
) {
|
||||
let mut visit_at_index = |idx: usize| match &item_tree[idx] {
|
||||
ItemTreeNode::Item { item, .. } => {
|
||||
visitor.visit_item(component, idx as isize, item.apply(base));
|
||||
visitor.visit_item(component, idx as isize, item.apply_pin(base));
|
||||
}
|
||||
ItemTreeNode::DynamicTree { index } => visit_dynamic(base, visitor.borrow_mut(), *index),
|
||||
};
|
||||
|
|
|
@ -108,7 +108,7 @@ unsafe extern "C" fn visit_children_item(
|
|||
&*(component.get_vtable() as *const ComponentVTable as *const ComponentDescription);
|
||||
let item_tree = &component_type.it;
|
||||
sixtyfps_corelib::item_tree::visit_item_tree(
|
||||
&*(component.as_ptr() as *const Instance),
|
||||
Pin::new_unchecked(&*(component.as_ptr() as *const Instance)),
|
||||
component,
|
||||
item_tree.as_slice().into(),
|
||||
index,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue