use std::collections::HashSet;
use crate::{
core::ui::{components::focus, messages::FocusChanged},
entity,
global::{CursorIcon, Vec2},
internal::{
conversion::{FromBindgen, IntoBindgen},
wit,
},
prelude::ModuleMessage,
};
pub use ambient_shared_types::MouseButton;
pub fn get() -> Input {
wit::client_input::get().from_bindgen()
}
pub fn get_previous() -> Input {
wit::client_input::get_previous().from_bindgen()
}
pub fn get_delta() -> (InputDelta, Input) {
let (p, c) = (get_previous(), get());
(c.delta(&p), c)
}
pub fn set_cursor(icon: CursorIcon) {
wit::client_input::set_cursor(icon.into_bindgen());
}
pub fn set_cursor_visible(visible: bool) {
wit::client_input::set_cursor_visible(visible);
}
pub fn set_cursor_lock(locked: bool) {
wit::client_input::set_cursor_lock(locked);
}
pub const GAME_FOCUS_ID: &str = "Game";
pub fn is_game_focused() -> bool {
entity::get_component(entity::resources(), focus()).unwrap_or_default() == GAME_FOCUS_ID
}
pub fn set_focus(focus_id: impl Into<String>) {
let focus_id = focus_id.into();
entity::set_component(entity::resources(), focus(), focus_id.clone());
FocusChanged {
from_external: false,
focus: focus_id,
}
.send_local_broadcast(true);
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum KeyCode {
Key1,
Key2,
Key3,
Key4,
Key5,
Key6,
Key7,
Key8,
Key9,
Key0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Escape,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
Snapshot,
Scroll,
Pause,
Insert,
Home,
Delete,
End,
PageDown,
PageUp,
Left,
Up,
Right,
Down,
Back,
Return,
Space,
Compose,
Caret,
Numlock,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
NumpadAdd,
NumpadDivide,
NumpadDecimal,
NumpadComma,
NumpadEnter,
NumpadEquals,
NumpadMultiply,
NumpadSubtract,
AbntC1,
AbntC2,
Apostrophe,
Apps,
Asterisk,
At,
Ax,
Backslash,
Calculator,
Capital,
Colon,
Comma,
Convert,
Equals,
Grave,
Kana,
Kanji,
LAlt,
LBracket,
LControl,
LShift,
LWin,
Mail,
MediaSelect,
MediaStop,
Minus,
Mute,
MyComputer,
NavigateForward,
NavigateBackward,
NextTrack,
NoConvert,
OEM102,
Period,
PlayPause,
Plus,
Power,
PrevTrack,
RAlt,
RBracket,
RControl,
RShift,
RWin,
Semicolon,
Slash,
Sleep,
Stop,
Sysrq,
Tab,
Underline,
Unlabeled,
VolumeDown,
VolumeUp,
Wake,
WebBack,
WebFavorites,
WebForward,
WebHome,
WebRefresh,
WebSearch,
WebStop,
Yen,
Copy,
Paste,
Cut,
}
impl FromBindgen for wit::client_input::VirtualKeyCode {
type Item = KeyCode;
fn from_bindgen(self) -> Self::Item {
match self {
Self::Key1 => Self::Item::Key1,
Self::Key2 => Self::Item::Key2,
Self::Key3 => Self::Item::Key3,
Self::Key4 => Self::Item::Key4,
Self::Key5 => Self::Item::Key5,
Self::Key6 => Self::Item::Key6,
Self::Key7 => Self::Item::Key7,
Self::Key8 => Self::Item::Key8,
Self::Key9 => Self::Item::Key9,
Self::Key0 => Self::Item::Key0,
Self::A => Self::Item::A,
Self::B => Self::Item::B,
Self::C => Self::Item::C,
Self::D => Self::Item::D,
Self::E => Self::Item::E,
Self::F => Self::Item::F,
Self::G => Self::Item::G,
Self::H => Self::Item::H,
Self::I => Self::Item::I,
Self::J => Self::Item::J,
Self::K => Self::Item::K,
Self::L => Self::Item::L,
Self::M => Self::Item::M,
Self::N => Self::Item::N,
Self::O => Self::Item::O,
Self::P => Self::Item::P,
Self::Q => Self::Item::Q,
Self::R => Self::Item::R,
Self::S => Self::Item::S,
Self::T => Self::Item::T,
Self::U => Self::Item::U,
Self::V => Self::Item::V,
Self::W => Self::Item::W,
Self::X => Self::Item::X,
Self::Y => Self::Item::Y,
Self::Z => Self::Item::Z,
Self::Escape => Self::Item::Escape,
Self::F1 => Self::Item::F1,
Self::F2 => Self::Item::F2,
Self::F3 => Self::Item::F3,
Self::F4 => Self::Item::F4,
Self::F5 => Self::Item::F5,
Self::F6 => Self::Item::F6,
Self::F7 => Self::Item::F7,
Self::F8 => Self::Item::F8,
Self::F9 => Self::Item::F9,
Self::F10 => Self::Item::F10,
Self::F11 => Self::Item::F11,
Self::F12 => Self::Item::F12,
Self::F13 => Self::Item::F13,
Self::F14 => Self::Item::F14,
Self::F15 => Self::Item::F15,
Self::F16 => Self::Item::F16,
Self::F17 => Self::Item::F17,
Self::F18 => Self::Item::F18,
Self::F19 => Self::Item::F19,
Self::F20 => Self::Item::F20,
Self::F21 => Self::Item::F21,
Self::F22 => Self::Item::F22,
Self::F23 => Self::Item::F23,
Self::F24 => Self::Item::F24,
Self::Snapshot => Self::Item::Snapshot,
Self::Scroll => Self::Item::Scroll,
Self::Pause => Self::Item::Pause,
Self::Insert => Self::Item::Insert,
Self::Home => Self::Item::Home,
Self::Delete => Self::Item::Delete,
Self::End => Self::Item::End,
Self::PageDown => Self::Item::PageDown,
Self::PageUp => Self::Item::PageUp,
Self::Left => Self::Item::Left,
Self::Up => Self::Item::Up,
Self::Right => Self::Item::Right,
Self::Down => Self::Item::Down,
Self::Back => Self::Item::Back,
Self::Return => Self::Item::Return,
Self::Space => Self::Item::Space,
Self::Compose => Self::Item::Compose,
Self::Caret => Self::Item::Caret,
Self::Numlock => Self::Item::Numlock,
Self::Numpad0 => Self::Item::Numpad0,
Self::Numpad1 => Self::Item::Numpad1,
Self::Numpad2 => Self::Item::Numpad2,
Self::Numpad3 => Self::Item::Numpad3,
Self::Numpad4 => Self::Item::Numpad4,
Self::Numpad5 => Self::Item::Numpad5,
Self::Numpad6 => Self::Item::Numpad6,
Self::Numpad7 => Self::Item::Numpad7,
Self::Numpad8 => Self::Item::Numpad8,
Self::Numpad9 => Self::Item::Numpad9,
Self::NumpadAdd => Self::Item::NumpadAdd,
Self::NumpadDivide => Self::Item::NumpadDivide,
Self::NumpadDecimal => Self::Item::NumpadDecimal,
Self::NumpadComma => Self::Item::NumpadComma,
Self::NumpadEnter => Self::Item::NumpadEnter,
Self::NumpadEquals => Self::Item::NumpadEquals,
Self::NumpadMultiply => Self::Item::NumpadMultiply,
Self::NumpadSubtract => Self::Item::NumpadSubtract,
Self::AbntC1 => Self::Item::AbntC1,
Self::AbntC2 => Self::Item::AbntC2,
Self::Apostrophe => Self::Item::Apostrophe,
Self::Apps => Self::Item::Apps,
Self::Asterisk => Self::Item::Asterisk,
Self::At => Self::Item::At,
Self::Ax => Self::Item::Ax,
Self::Backslash => Self::Item::Backslash,
Self::Calculator => Self::Item::Calculator,
Self::Capital => Self::Item::Capital,
Self::Colon => Self::Item::Colon,
Self::Comma => Self::Item::Comma,
Self::Convert => Self::Item::Convert,
Self::Equals => Self::Item::Equals,
Self::Grave => Self::Item::Grave,
Self::Kana => Self::Item::Kana,
Self::Kanji => Self::Item::Kanji,
Self::LAlt => Self::Item::LAlt,
Self::LBracket => Self::Item::LBracket,
Self::LControl => Self::Item::LControl,
Self::LShift => Self::Item::LShift,
Self::LWin => Self::Item::LWin,
Self::Mail => Self::Item::Mail,
Self::MediaSelect => Self::Item::MediaSelect,
Self::MediaStop => Self::Item::MediaStop,
Self::Minus => Self::Item::Minus,
Self::Mute => Self::Item::Mute,
Self::MyComputer => Self::Item::MyComputer,
Self::NavigateForward => Self::Item::NavigateForward,
Self::NavigateBackward => Self::Item::NavigateBackward,
Self::NextTrack => Self::Item::NextTrack,
Self::NoConvert => Self::Item::NoConvert,
Self::Oem102 => Self::Item::OEM102,
Self::Period => Self::Item::Period,
Self::PlayPause => Self::Item::PlayPause,
Self::Plus => Self::Item::Plus,
Self::Power => Self::Item::Power,
Self::PrevTrack => Self::Item::PrevTrack,
Self::RAlt => Self::Item::RAlt,
Self::RBracket => Self::Item::RBracket,
Self::RControl => Self::Item::RControl,
Self::RShift => Self::Item::RShift,
Self::RWin => Self::Item::RWin,
Self::Semicolon => Self::Item::Semicolon,
Self::Slash => Self::Item::Slash,
Self::Sleep => Self::Item::Sleep,
Self::Stop => Self::Item::Stop,
Self::Sysrq => Self::Item::Sysrq,
Self::Tab => Self::Item::Tab,
Self::Underline => Self::Item::Underline,
Self::Unlabeled => Self::Item::Unlabeled,
Self::VolumeDown => Self::Item::VolumeDown,
Self::VolumeUp => Self::Item::VolumeUp,
Self::Wake => Self::Item::Wake,
Self::WebBack => Self::Item::WebBack,
Self::WebFavorites => Self::Item::WebFavorites,
Self::WebForward => Self::Item::WebForward,
Self::WebHome => Self::Item::WebHome,
Self::WebRefresh => Self::Item::WebRefresh,
Self::WebSearch => Self::Item::WebSearch,
Self::WebStop => Self::Item::WebStop,
Self::Yen => Self::Item::Yen,
Self::Copy => Self::Item::Copy,
Self::Paste => Self::Item::Paste,
Self::Cut => Self::Item::Cut,
}
}
}
impl FromBindgen for wit::client_input::MouseButton {
type Item = MouseButton;
fn from_bindgen(self) -> Self::Item {
match self {
Self::Left => Self::Item::Left,
Self::Right => Self::Item::Right,
Self::Middle => Self::Item::Middle,
Self::Other(id) => Self::Item::Other(id),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Input {
pub keys: HashSet<KeyCode>,
pub mouse_position: Vec2,
pub mouse_delta: Vec2,
pub mouse_wheel: f32,
pub mouse_buttons: HashSet<MouseButton>,
}
impl FromBindgen for wit::client_input::Input {
type Item = Input;
fn from_bindgen(self) -> Self::Item {
Self::Item {
keys: self.keys.into_iter().map(|k| k.from_bindgen()).collect(),
mouse_position: self.mouse_position.from_bindgen(),
mouse_delta: self.mouse_delta.from_bindgen(),
mouse_wheel: self.mouse_wheel,
mouse_buttons: self
.mouse_buttons
.into_iter()
.map(|b| b.from_bindgen())
.collect(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct InputDelta {
pub keys: HashSet<KeyCode>,
pub keys_released: HashSet<KeyCode>,
pub mouse_position: Vec2,
pub mouse_wheel: f32,
pub mouse_buttons: HashSet<MouseButton>,
pub mouse_buttons_released: HashSet<MouseButton>,
}
impl Input {
pub fn delta(&self, previous: &Input) -> InputDelta {
let (p, c) = (previous, self);
InputDelta {
keys: &c.keys - &p.keys,
keys_released: &p.keys - &c.keys,
mouse_position: c.mouse_delta,
mouse_wheel: c.mouse_wheel - p.mouse_wheel,
mouse_buttons: &c.mouse_buttons - &p.mouse_buttons,
mouse_buttons_released: &p.mouse_buttons - &c.mouse_buttons,
}
}
}
impl IntoBindgen for CursorIcon {
type Item = wit::client_input::CursorIcon;
fn into_bindgen(self) -> Self::Item {
type Ci = CursorIcon;
type Wci = wit::client_input::CursorIcon;
match self {
Ci::Default => Wci::DefaultIcon,
Ci::Crosshair => Wci::Crosshair,
Ci::Hand => Wci::Hand,
Ci::Arrow => Wci::Arrow,
Ci::Move => Wci::Move,
Ci::Text => Wci::Text,
Ci::Wait => Wci::Wait,
Ci::Help => Wci::Help,
Ci::Progress => Wci::Progress,
Ci::NotAllowed => Wci::NotAllowed,
Ci::ContextMenu => Wci::ContextMenu,
Ci::Cell => Wci::Cell,
Ci::VerticalText => Wci::VerticalText,
Ci::Alias => Wci::Alias,
Ci::Copy => Wci::Copy,
Ci::NoDrop => Wci::NoDrop,
Ci::Grab => Wci::Grab,
Ci::Grabbing => Wci::Grabbing,
Ci::AllScroll => Wci::AllScroll,
Ci::ZoomIn => Wci::ZoomIn,
Ci::ZoomOut => Wci::ZoomOut,
Ci::EResize => Wci::EResize,
Ci::NResize => Wci::NResize,
Ci::NeResize => Wci::NeResize,
Ci::NwResize => Wci::NwResize,
Ci::SResize => Wci::SResize,
Ci::SeResize => Wci::SeResize,
Ci::SwResize => Wci::SwResize,
Ci::WResize => Wci::WResize,
Ci::EwResize => Wci::EwResize,
Ci::NsResize => Wci::NsResize,
Ci::NeswResize => Wci::NeswResize,
Ci::NwseResize => Wci::NwseResize,
Ci::ColResize => Wci::ColResize,
Ci::RowResize => Wci::RowResize,
}
}
}