use floem_winit::{
keyboard::{KeyCode, PhysicalKey},
window::Theme,
};
use peniko::kurbo::{Affine, Point, Size};
use crate::{
dropped_file::DroppedFileEvent,
keyboard::KeyEvent,
pointer::{PointerInputEvent, PointerMoveEvent, PointerWheelEvent},
};
pub enum EventPropagation {
Stop,
Continue,
}
impl EventPropagation {
pub fn is_continue(&self) -> bool {
matches!(self, EventPropagation::Continue)
}
pub fn is_stop(&self) -> bool {
matches!(self, EventPropagation::Stop)
}
pub fn is_processed(&self) -> bool {
matches!(self, EventPropagation::Stop)
}
}
#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
pub enum EventListener {
KeyDown,
KeyUp,
Click,
DoubleClick,
SecondaryClick,
DragStart,
DragEnd,
DragOver,
DragEnter,
DragLeave,
Drop,
PointerDown,
PointerMove,
PointerUp,
PointerEnter,
PointerLeave,
ImeEnabled,
ImeDisabled,
ImePreedit,
ImeCommit,
PointerWheel,
FocusGained,
FocusLost,
ThemeChanged,
WindowClosed,
WindowResized,
WindowMoved,
WindowGotFocus,
WindowLostFocus,
WindowMaximizeChanged,
DroppedFile,
}
#[derive(Debug, Clone)]
pub enum Event {
PointerDown(PointerInputEvent),
PointerUp(PointerInputEvent),
PointerMove(PointerMoveEvent),
PointerWheel(PointerWheelEvent),
PointerLeave,
DroppedFile(DroppedFileEvent),
KeyDown(KeyEvent),
KeyUp(KeyEvent),
ImeEnabled,
ImeDisabled,
ImePreedit {
text: String,
cursor: Option<(usize, usize)>,
},
ImeCommit(String),
WindowGotFocus,
WindowLostFocus,
WindowClosed,
WindowResized(Size),
WindowMoved(Point),
WindowMaximizeChanged(bool),
ThemeChanged(Theme),
FocusGained,
FocusLost,
}
impl Event {
pub fn needs_focus(&self) -> bool {
match self {
Event::PointerDown(_)
| Event::PointerUp(_)
| Event::PointerMove(_)
| Event::PointerWheel(_)
| Event::PointerLeave
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ImeCommit(_)
| Event::ThemeChanged(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowMaximizeChanged(_)
| Event::WindowGotFocus
| Event::WindowLostFocus
| Event::DroppedFile(_) => false,
Event::KeyDown(_) | Event::KeyUp(_) => true,
}
}
pub(crate) fn is_pointer(&self) -> bool {
match self {
Event::PointerDown(_)
| Event::PointerUp(_)
| Event::PointerMove(_)
| Event::PointerWheel(_)
| Event::PointerLeave => true,
Event::KeyDown(_)
| Event::KeyUp(_)
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ImeCommit(_)
| Event::ThemeChanged(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowMaximizeChanged(_)
| Event::WindowGotFocus
| Event::WindowLostFocus
| Event::DroppedFile(_) => false,
}
}
pub(crate) fn is_keyboard_trigger(&self) -> bool {
match self {
Event::KeyDown(key) | Event::KeyUp(key) => {
matches!(
key.key.physical_key,
PhysicalKey::Code(KeyCode::NumpadEnter)
| PhysicalKey::Code(KeyCode::Enter)
| PhysicalKey::Code(KeyCode::Space),
)
}
_ => false,
}
}
pub fn allow_disabled(&self) -> bool {
match self {
Event::PointerDown(_)
| Event::PointerUp(_)
| Event::PointerWheel(_)
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ImeCommit(_)
| Event::KeyDown(_)
| Event::KeyUp(_) => false,
Event::PointerLeave
| Event::PointerMove(_)
| Event::ThemeChanged(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowGotFocus
| Event::WindowMaximizeChanged(_)
| Event::WindowLostFocus
| Event::DroppedFile(_) => true,
}
}
pub fn point(&self) -> Option<Point> {
match self {
Event::PointerDown(pointer_event) | Event::PointerUp(pointer_event) => {
Some(pointer_event.pos)
}
Event::PointerMove(pointer_event) => Some(pointer_event.pos),
Event::PointerWheel(pointer_event) => Some(pointer_event.pos),
Event::DroppedFile(event) => Some(event.pos),
Event::PointerLeave
| Event::KeyDown(_)
| Event::KeyUp(_)
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ThemeChanged(_)
| Event::ImeCommit(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowMaximizeChanged(_)
| Event::WindowGotFocus
| Event::WindowLostFocus => None,
}
}
pub fn transform(mut self, transform: Affine) -> Event {
match &mut self {
Event::PointerDown(pointer_event) | Event::PointerUp(pointer_event) => {
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::PointerMove(pointer_event) => {
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::PointerWheel(pointer_event) => {
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::DroppedFile(event) => {
event.pos = transform.inverse() * event.pos;
}
Event::PointerLeave
| Event::KeyDown(_)
| Event::KeyUp(_)
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ThemeChanged(_)
| Event::ImeCommit(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowMaximizeChanged(_)
| Event::WindowGotFocus
| Event::WindowLostFocus => {}
}
self
}
pub fn listener(&self) -> Option<EventListener> {
match self {
Event::PointerDown(_) => Some(EventListener::PointerDown),
Event::PointerUp(_) => Some(EventListener::PointerUp),
Event::PointerMove(_) => Some(EventListener::PointerMove),
Event::PointerWheel(_) => Some(EventListener::PointerWheel),
Event::PointerLeave => Some(EventListener::PointerLeave),
Event::KeyDown(_) => Some(EventListener::KeyDown),
Event::KeyUp(_) => Some(EventListener::KeyUp),
Event::ImeEnabled => Some(EventListener::ImeEnabled),
Event::ImeDisabled => Some(EventListener::ImeDisabled),
Event::ImePreedit { .. } => Some(EventListener::ImePreedit),
Event::ImeCommit(_) => Some(EventListener::ImeCommit),
Event::WindowClosed => Some(EventListener::WindowClosed),
Event::WindowResized(_) => Some(EventListener::WindowResized),
Event::WindowMoved(_) => Some(EventListener::WindowMoved),
Event::WindowMaximizeChanged(_) => Some(EventListener::WindowMaximizeChanged),
Event::WindowGotFocus => Some(EventListener::WindowGotFocus),
Event::WindowLostFocus => Some(EventListener::WindowLostFocus),
Event::FocusLost => Some(EventListener::FocusLost),
Event::FocusGained => Some(EventListener::FocusGained),
Event::ThemeChanged(_) => Some(EventListener::ThemeChanged),
Event::DroppedFile(_) => Some(EventListener::DroppedFile),
}
}
}