bevy_feathers/controls/
virtual_keyboard.rs1use bevy_ecs::prelude::*;
2use bevy_input_focus::tab_navigation::TabGroup;
3use bevy_ui::Node;
4use bevy_ui::Val;
5use bevy_ui::{widget::Text, FlexDirection};
6use bevy_ui_widgets::{observe, Activate};
7
8use crate::controls::{button, ButtonProps};
9
10#[derive(EntityEvent)]
12pub struct VirtualKeyPressed<T> {
13 pub entity: Entity,
15 pub key: T,
17}
18
19pub fn virtual_keyboard<T>(
26 keys: impl Iterator<Item = Vec<T>> + Send + Sync + 'static,
27) -> impl Bundle
28where
29 T: AsRef<str> + Clone + Send + Sync + 'static,
30{
31 (
32 Node {
33 flex_direction: FlexDirection::Column,
34 row_gap: Val::Px(4.),
35 ..Default::default()
36 },
37 TabGroup::new(0),
38 Children::spawn(SpawnIter(keys.map(move |row| {
39 (
40 Node {
41 flex_direction: FlexDirection::Row,
42 column_gap: Val::Px(4.),
43 ..Default::default()
44 },
45 Children::spawn(SpawnIter(row.into_iter().map(move |key| {
46 (
47 button(ButtonProps::default(), (), Spawn(Text::new(key.as_ref()))),
48 observe(
49 move |activate: On<Activate>,
50 mut commands: Commands,
51 query: Query<&ChildOf>|
52 -> Result {
53 let virtual_keyboard =
54 query.get(query.get(activate.entity)?.parent())?.parent();
55 commands.trigger(VirtualKeyPressed {
56 entity: virtual_keyboard,
57 key: key.clone(),
58 });
59 Ok(())
60 },
61 ),
62 )
63 }))),
64 )
65 }))),
66 )
67}