Skip to main content

freya_components/
integration.rs

1use freya_core::{
2    integration::AppComponent,
3    layers::Layer,
4    prelude::*,
5};
6use torin::prelude::Position;
7
8use crate::context_menu::{
9    ContextMenu,
10    ContextMenuCloseRequest,
11};
12
13pub fn integration(app: AppComponent) -> impl IntoElement {
14    let platform = use_hook(Platform::get);
15    let mut context = use_hook(ContextMenu::get);
16
17    let on_global_key_down = move |e: Event<KeyboardEventData>| match e.key {
18        Key::Named(NamedKey::Tab) if e.modifiers == Modifiers::SHIFT => {
19            platform.send(UserEvent::FocusAccessibilityNode(
20                AccessibilityFocusStrategy::Backward(AccessibilityFocusMovement::OutsideGroup),
21            ));
22        }
23        Key::Named(NamedKey::Tab) if e.modifiers.is_empty() => {
24            platform.send(UserEvent::FocusAccessibilityNode(
25                AccessibilityFocusStrategy::Forward(AccessibilityFocusMovement::OutsideGroup),
26            ));
27        }
28        Key::Named(NamedKey::ArrowUp) if e.modifiers.is_empty() => {
29            platform.send(UserEvent::FocusAccessibilityNode(
30                AccessibilityFocusStrategy::Backward(AccessibilityFocusMovement::InsideGroup),
31            ));
32        }
33        Key::Named(NamedKey::ArrowDown) if e.modifiers.is_empty() => {
34            platform.send(UserEvent::FocusAccessibilityNode(
35                AccessibilityFocusStrategy::Forward(AccessibilityFocusMovement::InsideGroup),
36            ));
37        }
38        _ => {}
39    };
40
41    let on_global_pointer_move = move |e: Event<PointerEventData>| {
42        context.location.set(e.global_location());
43    };
44
45    rect()
46        .on_global_pointer_move(on_global_pointer_move)
47        .on_global_key_down(on_global_key_down)
48        .child(app)
49        .maybe_child(context.menu.read().clone().map(|(location, menu)| {
50            let location = location.to_f32();
51            rect()
52                .layer(Layer::Overlay)
53                .position(Position::new_global().left(location.x).top(location.y))
54                .child(menu.on_close(move |_| match (context.close_request)() {
55                    ContextMenuCloseRequest::None => {
56                        context.close_request.set(ContextMenuCloseRequest::Pending);
57                    }
58                    ContextMenuCloseRequest::Pending => {
59                        context.menu.set(None);
60                        context.close_request.set(ContextMenuCloseRequest::None);
61                    }
62                }))
63        }))
64}