Prepare for key event delivery to a specific focus item

Begin by routing key events through the component. In the future that
will direct the event to the focus item.
This commit is contained in:
Simon Hausmann 2020-09-24 16:32:06 +02:00
parent 2b76e9277a
commit aa5babffe1
8 changed files with 82 additions and 15 deletions

View file

@ -134,6 +134,8 @@ constexpr inline ItemTreeNode make_dyn_node(std::uintptr_t offset)
} }
using cbindgen_private::InputEventResult; using cbindgen_private::InputEventResult;
using cbindgen_private::KeyEvent;
using cbindgen_private::KeyEventResult;
using cbindgen_private::MouseEvent; using cbindgen_private::MouseEvent;
using cbindgen_private::sixtyfps_visit_item_tree; using cbindgen_private::sixtyfps_visit_item_tree;
namespace private_api { namespace private_api {
@ -174,6 +176,14 @@ inline InputEventResult process_input_event(ComponentRef component, int64_t &mou
component, mouse_event, window, *app_component, &mouse_grabber); component, mouse_event, window, *app_component, &mouse_grabber);
} }
} }
template<typename GetDynamic>
inline KeyEventResult process_key_event(ComponentRef component, const KeyEvent *key_event,
Slice<ItemTreeNode> tree, GetDynamic get_dynamic,
const ComponentWindow *window)
{
return cbindgen_private::sixtyfps_process_key_event(component, key_event, window);
}
} }
// layouts: // layouts:

View file

@ -133,9 +133,9 @@ pub mod re_exports {
PathArcTo, PathData, PathElement, PathEvent, PathLineTo, Point, Rect, Size, PathArcTo, PathData, PathElement, PathEvent, PathLineTo, Point, Rect, Size,
}; };
pub use sixtyfps_corelib::input::{ pub use sixtyfps_corelib::input::{
process_ungrabbed_mouse_event, InputEventResult, KeyCode, KeyEvent, KeyEventResult, process_key_event, process_ungrabbed_mouse_event, InputEventResult, KeyCode, KeyEvent,
KeyboardModifiers, MouseEvent, ALT_MODIFIER, CONTROL_MODIFIER, COPY_PASTE_MODIFIER, KeyEventResult, KeyboardModifiers, MouseEvent, ALT_MODIFIER, CONTROL_MODIFIER,
LOGO_MODIFIER, NO_MODIFIER, SHIFT_MODIFIER, COPY_PASTE_MODIFIER, LOGO_MODIFIER, NO_MODIFIER, SHIFT_MODIFIER,
}; };
pub use sixtyfps_corelib::item_tree::{ pub use sixtyfps_corelib::item_tree::{
item_offset, visit_item_tree, ItemTreeNode, ItemVisitorRefMut, ItemVisitorVTable, item_offset, visit_item_tree, ItemTreeNode, ItemVisitorRefMut, ItemVisitorVTable,

View file

@ -858,6 +858,24 @@ fn generate_component(
}), }),
)); ));
component_struct.members.push((
Access::Private,
Declaration::Function(Function {
name: "key_event".into(),
signature:
"(sixtyfps::private_api::ComponentRef component, const sixtyfps::KeyEvent *key_event, const sixtyfps::private_api::ComponentWindow *window) -> sixtyfps::KeyEventResult"
.into(),
is_static: true,
statements: Some(vec![
format!(" auto self = reinterpret_cast<{}*>(component.instance);", component_id),
"return sixtyfps::private_api::process_key_event(component, key_event, item_tree(), [self](int dyn_index, [[maybe_unused]] int rep_index) {".into(),
format!(" switch(dyn_index) {{ {} }};", repeated_input_branch.join("")),
" return sixtyfps::private_api::ComponentRef{nullptr, nullptr};\n}, window);".into(),
]),
..Default::default()
}),
));
component_struct.members.push(( component_struct.members.push((
Access::Public, // FIXME: we call this function from tests Access::Public, // FIXME: we call this function from tests
Declaration::Function(Function { Declaration::Function(Function {
@ -885,7 +903,9 @@ fn generate_component(
declarations.push(Declaration::Var(Var { declarations.push(Declaration::Var(Var {
ty: "const sixtyfps::private_api::ComponentVTable".to_owned(), ty: "const sixtyfps::private_api::ComponentVTable".to_owned(),
name: format!("{}::component_type", component_id), name: format!("{}::component_type", component_id),
init: Some("{ visit_children, nullptr, compute_layout, input_event }".to_owned()), init: Some(
"{ visit_children, nullptr, compute_layout, input_event, key_event }".to_owned(),
),
})); }));
declarations.append(&mut file.declarations); declarations.append(&mut file.declarations);

View file

@ -577,6 +577,12 @@ fn generate_component(
status status
} }
fn key_event(self: ::core::pin::Pin<&Self>, key_event : &sixtyfps::re_exports::KeyEvent, window: &sixtyfps::re_exports::ComponentWindow)
-> sixtyfps::re_exports::KeyEventResult{
use sixtyfps::re_exports::*;
process_key_event(VRef::new_pin(self), key_event, window)
}
#layouts #layouts
} }

View file

@ -12,7 +12,7 @@ LICENSE END */
//! This module contains the basic datastructures that are exposed to the C API //! This module contains the basic datastructures that are exposed to the C API
use crate::eventloop::ComponentWindow; use crate::eventloop::ComponentWindow;
use crate::input::{InputEventResult, MouseEvent}; use crate::input::{InputEventResult, KeyEvent, KeyEventResult, MouseEvent};
use crate::item_tree::{ItemVisitorVTable, TraversalOrder, VisitChildrenResult}; use crate::item_tree::{ItemVisitorVTable, TraversalOrder, VisitChildrenResult};
use crate::layout::LayoutInfo; use crate::layout::LayoutInfo;
use vtable::*; use vtable::*;
@ -44,6 +44,13 @@ pub struct ComponentVTable {
&ComponentWindow, &ComponentWindow,
&core::pin::Pin<VRef<ComponentVTable>>, &core::pin::Pin<VRef<ComponentVTable>>,
) -> InputEventResult, ) -> InputEventResult,
/// key event
pub key_event: extern "C" fn(
core::pin::Pin<VRef<ComponentVTable>>,
&KeyEvent,
&ComponentWindow,
) -> KeyEventResult,
} }
/// Alias for `vtable::VRef<ComponentVTable>` which represent a pointer to a `dyn Component` with /// Alias for `vtable::VRef<ComponentVTable>` which represent a pointer to a `dyn Component` with

View file

@ -620,11 +620,7 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
event: &KeyEvent, event: &KeyEvent,
component: core::pin::Pin<crate::component::ComponentRef>, component: core::pin::Pin<crate::component::ComponentRef>,
) { ) {
crate::input::process_key_event( component.as_ref().key_event(event, &crate::eventloop::ComponentWindow::new(self.clone()));
component,
event,
&crate::eventloop::ComponentWindow::new(self.clone()),
)
} }
fn with_platform_window(&self, callback: &dyn Fn(&winit::window::Window)) { fn with_platform_window(&self, callback: &dyn Fn(&winit::window::Window)) {

View file

@ -522,16 +522,21 @@ pub fn process_key_event(
component: ComponentRefPin, component: ComponentRefPin,
event: &KeyEvent, event: &KeyEvent,
window: &crate::eventloop::ComponentWindow, window: &crate::eventloop::ComponentWindow,
) { ) -> KeyEventResult {
let mut result = KeyEventResult::EventIgnored;
crate::item_tree::visit_items( crate::item_tree::visit_items(
component, component,
crate::item_tree::TraversalOrder::BackToFront, crate::item_tree::TraversalOrder::BackToFront,
|_, item, _| match item.as_ref().key_event(event, window) { |_, item, _| {
result = item.as_ref().key_event(event, window);
match result {
KeyEventResult::EventAccepted => ItemVisitorResult::Abort, KeyEventResult::EventAccepted => ItemVisitorResult::Abort,
KeyEventResult::EventIgnored => ItemVisitorResult::Continue(()), KeyEventResult::EventIgnored => ItemVisitorResult::Continue(()),
}
}, },
(), (),
); );
result
} }
pub(crate) mod ffi { pub(crate) mod ffi {
@ -560,4 +565,13 @@ pub(crate) mod ffi {
) -> (InputEventResult, crate::item_tree::VisitChildrenResult) { ) -> (InputEventResult, crate::item_tree::VisitChildrenResult) {
process_grabbed_mouse_event(component, item, offset, event, old_grab) process_grabbed_mouse_event(component, item, offset, event, old_grab)
}*/ }*/
#[no_mangle]
pub extern "C" fn sixtyfps_process_key_event(
component: core::pin::Pin<crate::component::ComponentRef>,
event: &KeyEvent,
window: &crate::eventloop::ComponentWindow,
) -> KeyEventResult {
process_key_event(component, event, window)
}
} }

View file

@ -574,7 +574,13 @@ fn generate_component<'id>(
todo!() todo!()
} }
let t = ComponentVTable { visit_children_item, layout_info, compute_layout, input_event }; let t = ComponentVTable {
visit_children_item,
layout_info,
compute_layout,
input_event,
key_event,
};
let t = ComponentDescription { let t = ComponentDescription {
ct: t, ct: t,
dynamic_type: builder.build(), dynamic_type: builder.build(),
@ -1129,6 +1135,14 @@ extern "C" fn input_event(
status status
} }
extern "C" fn key_event(
component: ComponentRefPin,
key_event: &sixtyfps_corelib::input::KeyEvent,
window: &sixtyfps_corelib::eventloop::ComponentWindow,
) -> sixtyfps_corelib::input::KeyEventResult {
sixtyfps_corelib::input::process_key_event(component, key_event, window)
}
extern "C" fn compute_layout(component: ComponentRefPin) { extern "C" fn compute_layout(component: ComponentRefPin) {
generativity::make_guard!(guard); generativity::make_guard!(guard);
// This is fine since we can only be called with a component that with our vtable which is a ComponentDescription // This is fine since we can only be called with a component that with our vtable which is a ComponentDescription