mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-03 15:14:35 +00:00
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:
parent
2b76e9277a
commit
aa5babffe1
8 changed files with 82 additions and 15 deletions
|
@ -134,6 +134,8 @@ constexpr inline ItemTreeNode make_dyn_node(std::uintptr_t offset)
|
|||
}
|
||||
|
||||
using cbindgen_private::InputEventResult;
|
||||
using cbindgen_private::KeyEvent;
|
||||
using cbindgen_private::KeyEventResult;
|
||||
using cbindgen_private::MouseEvent;
|
||||
using cbindgen_private::sixtyfps_visit_item_tree;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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:
|
||||
|
|
|
@ -133,9 +133,9 @@ pub mod re_exports {
|
|||
PathArcTo, PathData, PathElement, PathEvent, PathLineTo, Point, Rect, Size,
|
||||
};
|
||||
pub use sixtyfps_corelib::input::{
|
||||
process_ungrabbed_mouse_event, InputEventResult, KeyCode, KeyEvent, KeyEventResult,
|
||||
KeyboardModifiers, MouseEvent, ALT_MODIFIER, CONTROL_MODIFIER, COPY_PASTE_MODIFIER,
|
||||
LOGO_MODIFIER, NO_MODIFIER, SHIFT_MODIFIER,
|
||||
process_key_event, process_ungrabbed_mouse_event, InputEventResult, KeyCode, KeyEvent,
|
||||
KeyEventResult, KeyboardModifiers, MouseEvent, ALT_MODIFIER, CONTROL_MODIFIER,
|
||||
COPY_PASTE_MODIFIER, LOGO_MODIFIER, NO_MODIFIER, SHIFT_MODIFIER,
|
||||
};
|
||||
pub use sixtyfps_corelib::item_tree::{
|
||||
item_offset, visit_item_tree, ItemTreeNode, ItemVisitorRefMut, ItemVisitorVTable,
|
||||
|
|
|
@ -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 {".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((
|
||||
Access::Public, // FIXME: we call this function from tests
|
||||
Declaration::Function(Function {
|
||||
|
@ -885,7 +903,9 @@ fn generate_component(
|
|||
declarations.push(Declaration::Var(Var {
|
||||
ty: "const sixtyfps::private_api::ComponentVTable".to_owned(),
|
||||
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);
|
||||
|
|
|
@ -577,6 +577,12 @@ fn generate_component(
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ LICENSE END */
|
|||
//! This module contains the basic datastructures that are exposed to the C API
|
||||
|
||||
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::layout::LayoutInfo;
|
||||
use vtable::*;
|
||||
|
@ -44,6 +44,13 @@ pub struct ComponentVTable {
|
|||
&ComponentWindow,
|
||||
&core::pin::Pin<VRef<ComponentVTable>>,
|
||||
) -> 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
|
||||
|
|
|
@ -620,11 +620,7 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
|
|||
event: &KeyEvent,
|
||||
component: core::pin::Pin<crate::component::ComponentRef>,
|
||||
) {
|
||||
crate::input::process_key_event(
|
||||
component,
|
||||
event,
|
||||
&crate::eventloop::ComponentWindow::new(self.clone()),
|
||||
)
|
||||
component.as_ref().key_event(event, &crate::eventloop::ComponentWindow::new(self.clone()));
|
||||
}
|
||||
|
||||
fn with_platform_window(&self, callback: &dyn Fn(&winit::window::Window)) {
|
||||
|
|
|
@ -522,16 +522,21 @@ pub fn process_key_event(
|
|||
component: ComponentRefPin,
|
||||
event: &KeyEvent,
|
||||
window: &crate::eventloop::ComponentWindow,
|
||||
) {
|
||||
) -> KeyEventResult {
|
||||
let mut result = KeyEventResult::EventIgnored;
|
||||
crate::item_tree::visit_items(
|
||||
component,
|
||||
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::EventIgnored => ItemVisitorResult::Continue(()),
|
||||
}
|
||||
},
|
||||
(),
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) mod ffi {
|
||||
|
@ -560,4 +565,13 @@ pub(crate) mod ffi {
|
|||
) -> (InputEventResult, crate::item_tree::VisitChildrenResult) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -574,7 +574,13 @@ fn generate_component<'id>(
|
|||
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 {
|
||||
ct: t,
|
||||
dynamic_type: builder.build(),
|
||||
|
@ -1129,6 +1135,14 @@ extern "C" fn input_event(
|
|||
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) {
|
||||
generativity::make_guard!(guard);
|
||||
// This is fine since we can only be called with a component that with our vtable which is a ComponentDescription
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue