C++: Fix input event within repeater

This commit is contained in:
Olivier Goffart 2020-08-10 08:55:42 +02:00
parent 9b0dfa14b5
commit cc5d5cc92b
2 changed files with 26 additions and 8 deletions

View file

@ -82,10 +82,10 @@ constexpr inline ItemTreeNode make_dyn_node(std::uintptr_t offset)
using internal::sixtyfps_visit_item_tree; using internal::sixtyfps_visit_item_tree;
using internal::MouseEvent; using internal::MouseEvent;
using internal::InputEventResult; using internal::InputEventResult;
template<typename HandleDynamic> template<typename GetDynamic>
inline InputEventResult process_input_event( inline InputEventResult process_input_event(
ComponentRef component, int64_t &mouse_grabber, MouseEvent mouse_event, ComponentRef component, int64_t &mouse_grabber, MouseEvent mouse_event,
Slice<ItemTreeNode> tree, HandleDynamic handle_dynamic) Slice<ItemTreeNode> tree, GetDynamic get_dynamic)
{ {
if (mouse_grabber != -1) { if (mouse_grabber != -1) {
auto item_index = mouse_grabber & 0xffffffff; auto item_index = mouse_grabber & 0xffffffff;
@ -101,8 +101,10 @@ inline InputEventResult process_input_event(
reinterpret_cast<char*>(component.instance) + item_node.item.item.offset, reinterpret_cast<char*>(component.instance) + item_node.item.item.offset,
} , mouse_event); } , mouse_event);
break; break;
case ItemTreeNode::Tag::DynamicTree: case ItemTreeNode::Tag::DynamicTree: {
result = handle_dynamic(item_node.dynamic_tree.index, rep_index, &mouse_event); ComponentRef comp = get_dynamic(item_node.dynamic_tree.index, rep_index);
result = comp.vtable->input_event(comp, mouse_event);
}
break; break;
} }
if (result != InputEventResult::GrabMouse) { if (result != InputEventResult::GrabMouse) {
@ -177,15 +179,20 @@ struct Repeater
intptr_t visit(ItemVisitorRefMut visitor) const intptr_t visit(ItemVisitorRefMut visitor) const
{ {
for (auto i = 0; i < data.size(); ++i) { for (std::size_t i = 0; i < data.size(); ++i) {
const auto &x = data.at(i); VRef<ComponentVTable> ref = item_at(i);
VRef<ComponentVTable> ref { &C::component_type, x.get() };
if (ref.vtable->visit_children_item(ref, -1, visitor) != -1) { if (ref.vtable->visit_children_item(ref, -1, visitor) != -1) {
return i; return i;
} }
} }
return -1; return -1;
} }
VRef<ComponentVTable> item_at(int i) const {
const auto &x = data.at(i);
return { &C::component_type, x.get() };
}
}; };
Flickable::Flickable() Flickable::Flickable()

View file

@ -357,6 +357,7 @@ fn handle_repeater(
component_struct: &mut Struct, component_struct: &mut Struct,
init: &mut Vec<String>, init: &mut Vec<String>,
children_repeater_cases: &mut Vec<String>, children_repeater_cases: &mut Vec<String>,
repeated_input_branch: &mut Vec<String>,
) { ) {
let repeater_id = let repeater_id =
format!("repeater_{}", base_component.parent_element.upgrade().unwrap().borrow().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(( component_struct.members.push((
Access::Private, Access::Private,
Declaration::Var(Var { Declaration::Var(Var {
@ -661,6 +668,7 @@ fn generate_component(
} }
let mut children_visitor_case = vec![]; let mut children_visitor_case = vec![];
let mut repeated_input_branch = vec![];
let mut tree_array = vec![]; let mut tree_array = vec![];
let mut repeater_count = 0; let mut repeater_count = 0;
super::build_array_helper(component, |item_rc, children_offset, is_flickable_rect| { super::build_array_helper(component, |item_rc, children_offset, is_flickable_rect| {
@ -692,6 +700,7 @@ fn generate_component(
&mut component_struct, &mut component_struct,
&mut init, &mut init,
&mut children_visitor_case, &mut children_visitor_case,
&mut repeated_input_branch,
); );
repeater_count += 1; repeater_count += 1;
} else { } else {
@ -770,7 +779,9 @@ fn generate_component(
is_static: true, is_static: true,
statements: Some(vec![ statements: Some(vec![
format!(" auto self = reinterpret_cast<{}*>(component.instance);", component_id), 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() ..Default::default()
}), }),