diff --git a/api/sixtyfps-cpp/include/sixtyfps.h b/api/sixtyfps-cpp/include/sixtyfps.h index 81f7e1cd5..40bf2bfb5 100644 --- a/api/sixtyfps-cpp/include/sixtyfps.h +++ b/api/sixtyfps-cpp/include/sixtyfps.h @@ -82,10 +82,10 @@ constexpr inline ItemTreeNode make_dyn_node(std::uintptr_t offset) using internal::sixtyfps_visit_item_tree; using internal::MouseEvent; using internal::InputEventResult; -template +template inline InputEventResult process_input_event( ComponentRef component, int64_t &mouse_grabber, MouseEvent mouse_event, - Slice tree, HandleDynamic handle_dynamic) + Slice tree, GetDynamic get_dynamic) { if (mouse_grabber != -1) { auto item_index = mouse_grabber & 0xffffffff; @@ -101,8 +101,10 @@ inline InputEventResult process_input_event( reinterpret_cast(component.instance) + item_node.item.item.offset, } , mouse_event); break; - case ItemTreeNode::Tag::DynamicTree: - result = handle_dynamic(item_node.dynamic_tree.index, rep_index, &mouse_event); + case ItemTreeNode::Tag::DynamicTree: { + ComponentRef comp = get_dynamic(item_node.dynamic_tree.index, rep_index); + result = comp.vtable->input_event(comp, mouse_event); + } break; } if (result != InputEventResult::GrabMouse) { @@ -177,15 +179,20 @@ struct Repeater intptr_t visit(ItemVisitorRefMut visitor) const { - for (auto i = 0; i < data.size(); ++i) { - const auto &x = data.at(i); - VRef ref { &C::component_type, x.get() }; + for (std::size_t i = 0; i < data.size(); ++i) { + VRef ref = item_at(i); if (ref.vtable->visit_children_item(ref, -1, visitor) != -1) { return i; } } return -1; } + + VRef item_at(int i) const { + const auto &x = data.at(i); + return { &C::component_type, x.get() }; + } + }; Flickable::Flickable() diff --git a/sixtyfps_compiler/generator/cpp.rs b/sixtyfps_compiler/generator/cpp.rs index 1be7ceea8..d3306f801 100644 --- a/sixtyfps_compiler/generator/cpp.rs +++ b/sixtyfps_compiler/generator/cpp.rs @@ -357,6 +357,7 @@ fn handle_repeater( component_struct: &mut Struct, init: &mut Vec, children_repeater_cases: &mut Vec, + repeated_input_branch: &mut Vec, ) { let repeater_id = format!("repeater_{}", base_component.parent_element.upgrade().unwrap().borrow().id); @@ -407,6 +408,12 @@ fn handle_repeater( )); } + repeated_input_branch.push(format!( + "\n case {i}: return self->{id}.item_at(rep_index);", + i = repeater_count, + id = repeater_id, + )); + component_struct.members.push(( Access::Private, Declaration::Var(Var { @@ -661,6 +668,7 @@ fn generate_component( } let mut children_visitor_case = vec![]; + let mut repeated_input_branch = vec![]; let mut tree_array = vec![]; let mut repeater_count = 0; super::build_array_helper(component, |item_rc, children_offset, is_flickable_rect| { @@ -692,6 +700,7 @@ fn generate_component( &mut component_struct, &mut init, &mut children_visitor_case, + &mut repeated_input_branch, ); repeater_count += 1; } else { @@ -770,7 +779,9 @@ fn generate_component( is_static: true, statements: Some(vec![ format!(" auto self = reinterpret_cast<{}*>(component.instance);", component_id), - "return sixtyfps::process_input_event(component, self->mouse_grabber, mouse_event, item_tree(), [](auto...) { return sixtyfps::InputEventResult::EventIgnored; });".into() + "return sixtyfps::process_input_event(component, self->mouse_grabber, mouse_event, item_tree(), [self](int dyn_index, [[maybe_unused]] int rep_index) {".into(), + format!(" switch(dyn_index) {{ {} }};", repeated_input_branch.join("")), + " return sixtyfps::ComponentRef{nullptr, nullptr};\n});".into(), ]), ..Default::default() }),