use std::str::FromStr;
use bitflags::bitflags;
use keyboard_types::{Code, Key, Location, Modifiers};
use smol_str::SmolStr;
#[derive(Default)]
pub struct EventState {
cancelled: bool,
propagation_stopped: bool,
redraw_requested: bool,
}
impl EventState {
#[inline(always)]
pub fn prevent_default(&mut self) {
self.cancelled = true;
}
#[inline(always)]
pub fn stop_propagation(&mut self) {
self.propagation_stopped = true;
}
#[inline(always)]
pub fn request_redraw(&mut self) {
self.redraw_requested = true;
}
#[inline(always)]
pub fn is_cancelled(&self) -> bool {
self.cancelled
}
#[inline(always)]
pub fn propagation_is_stopped(&self) -> bool {
self.propagation_stopped
}
#[inline(always)]
pub fn redraw_is_requested(&self) -> bool {
self.redraw_requested
}
}
#[derive(Debug, Clone)]
#[repr(u8)]
pub enum UiEvent {
MouseMove(BlitzMouseButtonEvent),
MouseUp(BlitzMouseButtonEvent),
MouseDown(BlitzMouseButtonEvent),
KeyUp(BlitzKeyEvent),
KeyDown(BlitzKeyEvent),
Ime(BlitzImeEvent),
}
impl UiEvent {
pub fn discriminant(&self) -> u8 {
unsafe { *<*const _>::from(self).cast::<u8>() }
}
}
#[derive(Debug, Clone)]
pub struct DomEvent {
pub target: usize,
pub bubbles: bool,
pub cancelable: bool,
pub data: DomEventData,
pub request_redraw: bool,
}
impl DomEvent {
pub fn new(target: usize, data: DomEventData) -> Self {
Self {
target,
bubbles: data.bubbles(),
cancelable: data.cancelable(),
data,
request_redraw: false,
}
}
pub fn name(&self) -> &'static str {
self.data.name()
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u8)]
pub enum DomEventKind {
MouseMove,
MouseDown,
MouseUp,
Click,
KeyPress,
KeyDown,
KeyUp,
Input,
Ime,
}
impl DomEventKind {
pub fn discriminant(self) -> u8 {
self as u8
}
}
impl FromStr for DomEventKind {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s.trim_start_matches("on") {
"mousemove" => Ok(Self::MouseMove),
"mousedown" => Ok(Self::MouseDown),
"mouseup" => Ok(Self::MouseUp),
"click" => Ok(Self::Click),
"keypress" => Ok(Self::KeyPress),
"keydown" => Ok(Self::KeyDown),
"keyup" => Ok(Self::KeyUp),
"input" => Ok(Self::Input),
"composition" => Ok(Self::Ime),
_ => Err(()),
}
}
}
#[derive(Debug, Clone)]
#[repr(u8)]
pub enum DomEventData {
MouseMove(BlitzMouseButtonEvent),
MouseDown(BlitzMouseButtonEvent),
MouseUp(BlitzMouseButtonEvent),
Click(BlitzMouseButtonEvent),
KeyPress(BlitzKeyEvent),
KeyDown(BlitzKeyEvent),
KeyUp(BlitzKeyEvent),
Input(BlitzInputEvent),
Ime(BlitzImeEvent),
}
impl DomEventData {
pub fn discriminant(&self) -> u8 {
unsafe { *<*const _>::from(self).cast::<u8>() }
}
}
impl DomEventData {
pub fn name(&self) -> &'static str {
match self {
Self::MouseMove { .. } => "mousemove",
Self::MouseDown { .. } => "mousedown",
Self::MouseUp { .. } => "mouseup",
Self::Click { .. } => "click",
Self::KeyPress { .. } => "keypress",
Self::KeyDown { .. } => "keydown",
Self::KeyUp { .. } => "keyup",
Self::Input { .. } => "input",
Self::Ime { .. } => "composition",
}
}
pub fn kind(&self) -> DomEventKind {
match self {
Self::MouseMove { .. } => DomEventKind::MouseMove,
Self::MouseDown { .. } => DomEventKind::MouseDown,
Self::MouseUp { .. } => DomEventKind::MouseUp,
Self::Click { .. } => DomEventKind::Click,
Self::KeyPress { .. } => DomEventKind::KeyPress,
Self::KeyDown { .. } => DomEventKind::KeyDown,
Self::KeyUp { .. } => DomEventKind::KeyUp,
Self::Input { .. } => DomEventKind::Input,
Self::Ime { .. } => DomEventKind::Ime,
}
}
pub fn cancelable(&self) -> bool {
match self {
Self::MouseMove { .. } => true,
Self::MouseDown { .. } => true,
Self::MouseUp { .. } => true,
Self::Click { .. } => true,
Self::KeyDown { .. } => true,
Self::KeyUp { .. } => true,
Self::KeyPress { .. } => true,
Self::Ime { .. } => true,
Self::Input { .. } => false,
}
}
pub fn bubbles(&self) -> bool {
match self {
Self::MouseMove { .. } => true,
Self::MouseDown { .. } => true,
Self::MouseUp { .. } => true,
Self::Click { .. } => true,
Self::KeyDown { .. } => true,
Self::KeyUp { .. } => true,
Self::KeyPress { .. } => true,
Self::Ime { .. } => true,
Self::Input { .. } => true,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct HitResult {
pub node_id: usize,
pub x: f32,
pub y: f32,
}
#[derive(Clone, Debug)]
pub struct BlitzMouseButtonEvent {
pub x: f32,
pub y: f32,
pub button: MouseEventButton,
pub buttons: MouseEventButtons,
pub mods: Modifiers,
}
bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct MouseEventButtons: u8 {
const None = 0b0000_0000;
const Primary = 0b0000_0001;
const Secondary = 0b0000_0010;
const Auxiliary = 0b0000_0100;
const Fourth = 0b0000_1000;
const Fifth = 0b0001_0000;
}
}
impl Default for MouseEventButtons {
fn default() -> Self {
Self::None
}
}
impl From<MouseEventButton> for MouseEventButtons {
fn from(value: MouseEventButton) -> Self {
match value {
MouseEventButton::Main => Self::Primary,
MouseEventButton::Auxiliary => Self::Auxiliary,
MouseEventButton::Secondary => Self::Secondary,
MouseEventButton::Fourth => Self::Fourth,
MouseEventButton::Fifth => Self::Fifth,
}
}
}
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub enum MouseEventButton {
#[default]
Main = 0,
Auxiliary = 1,
Secondary = 2,
Fourth = 3,
Fifth = 4,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum KeyState {
Pressed,
Released,
}
impl KeyState {
pub fn is_pressed(self) -> bool {
matches!(self, Self::Pressed)
}
}
#[derive(Clone, Debug)]
pub struct BlitzKeyEvent {
pub key: Key,
pub code: Code,
pub modifiers: Modifiers,
pub location: Location,
pub is_auto_repeating: bool,
pub is_composing: bool,
pub state: KeyState,
pub text: Option<SmolStr>,
}
#[derive(Clone, Debug)]
pub struct BlitzInputEvent {
pub value: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum BlitzImeEvent {
Enabled,
Preedit(String, Option<(usize, usize)>),
Commit(String),
Disabled,
}