//! Virtual keyboard example use bevy::{ color::palettes::css::{NAVY, WHITE}, feathers::{ controls::{VirtualKeyPressed, VirtualKeyboard}, dark_theme::create_dark_theme, theme::UiTheme, FeathersPlugins, }, input_focus::{ tab_navigation::{TabGroup, TabIndex}, AutoFocus, InputFocus, }, prelude::*, text::{EditableText, TextCursorStyle, TextEdit}, ui_widgets::TextInput, }; fn main() { App::new() .add_plugins((DefaultPlugins, FeathersPlugins)) .insert_resource(UiTheme(create_dark_theme())) .add_systems(Startup, scene.spawn()) .run(); } fn on_virtual_key_pressed( virtual_key_pressed: On>, mut query: Query<(Entity, &mut EditableText)>, mut input_focus: ResMut, ) { println!("Virtual keyboard key pressed: {}", virtual_key_pressed.key); let Ok((entity_id, mut text)) = query.single_mut() else { return; }; text.queue_edit(match virtual_key_pressed.key { "space" => TextEdit::Insert(" ".into()), "enter" => TextEdit::Insert("\n".into()), "backspace" => TextEdit::Backspace, "left" => TextEdit::Left(false), "right" => TextEdit::Right(false), "up" => TextEdit::Up(false), "down" => TextEdit::Down(false), "home" => TextEdit::LineStart(false), "end" => TextEdit::LineEnd(false), key if key.len() == 1 => TextEdit::Insert(key.into()), _ => return, }); input_focus.set(entity_id, bevy::input_focus::FocusCause::Navigated); } fn scene() -> impl SceneList { bsn_list! { Camera2d -- @text_input() -- @keyboard() } } fn keyboard() -> impl Scene { let keys = [ vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ","], vec!["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"], vec!["A", "S", "D", "F", "G", "H", "J", "K", "L", "'"], vec!["Z", "X", "C", "V", "B", "N", "M", "-", "/"], vec!["space", "enter", "backspace"], vec!["left", "right", "up", "down", "home", "end"], ]; bsn! { Node { width: percent(100), bottom: px(0), flex_direction: FlexDirection::Column, position_type: PositionType::Absolute, align_items: AlignItems::Center, justify_content: JustifyContent::End, } Children [ Node { flex_direction: FlexDirection::Column, border: px(5), row_gap: px(5), padding: px(5), align_items: AlignItems::Center, margin: px(25), border_radius: BorderRadius::all(px(10)), } BackgroundColor(NAVY) BorderColor::all(Color::WHITE) Children [ Text("virtual keyboard") -- @VirtualKeyboard::<&str> { @keys: keys } on(on_virtual_key_pressed) ] ] } } fn text_input() -> impl Scene { bsn! { Node { width: percent(100), padding: px(25), position_type: PositionType::Absolute, align_items: AlignItems::Center, justify_content: JustifyContent::Center, } TabGroup Children [ Node { width: percent(80), border: px(5), padding: px(5), flex_grow: 0.0, border_radius: BorderRadius::all(px(10)), } BorderColor::from(WHITE) TextInput EditableText { visible_lines: { Some(5.) } allow_newlines: true, } TextLayout::no_wrap() TextCursorStyle { color: WHITE } TextFont { font_size: FontSize::Px(25.), } TabIndex(0) AutoFocus ] } }