use std::ops::BitOr;
use std::time::Duration;
use densa_core::Point;
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum Event<'a> {
Pointer(PointerEvent),
Key(KeyEvent<'a>),
Ime(Ime<'a>),
FocusGained,
FocusLost,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub struct PointerEvent {
pub kind: PointerKind,
pub position: Point,
pub modifiers: Modifiers,
pub time: Duration,
pub clicks: u8,
}
impl PointerEvent {
pub fn new(kind: PointerKind, position: Point) -> Self {
Self {
kind,
position,
modifiers: Modifiers::NONE,
time: Duration::ZERO,
clicks: 1,
}
}
#[must_use]
pub fn with_modifiers(mut self, modifiers: Modifiers) -> Self {
self.modifiers = modifiers;
self
}
#[must_use]
pub fn at(mut self, time: Duration) -> Self {
self.time = time;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum PointerKind {
Down(PointerButton),
Up(PointerButton),
Move,
Scroll(ScrollDelta),
Enter,
Leave,
Cancel,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum PointerButton {
Primary,
Secondary,
Middle,
Other(u16),
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum ScrollDelta {
Lines(f32, f32),
Pixels(f32, f32),
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub struct KeyEvent<'a> {
pub key: Key<'a>,
pub text: Option<&'a str>,
pub pressed: bool,
pub repeat: bool,
pub modifiers: Modifiers,
}
impl<'a> KeyEvent<'a> {
pub fn down(key: Key<'a>) -> Self {
Self {
key,
text: None,
pressed: true,
repeat: false,
modifiers: Modifiers::NONE,
}
}
pub fn up(key: Key<'a>) -> Self {
Self {
pressed: false,
..Self::down(key)
}
}
#[must_use]
pub fn with_text(mut self, text: &'a str) -> Self {
self.text = Some(text);
self
}
#[must_use]
pub fn with_modifiers(mut self, modifiers: Modifiers) -> Self {
self.modifiers = modifiers;
self
}
#[must_use]
pub fn repeated(mut self) -> Self {
self.repeat = true;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Key<'a> {
Named(NamedKey),
Character(&'a str),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum NamedKey {
Enter,
Tab,
Space,
Backspace,
Delete,
Escape,
ArrowLeft,
ArrowRight,
ArrowUp,
ArrowDown,
Home,
End,
PageUp,
PageDown,
Insert,
Shift,
Control,
Alt,
Super,
ContextMenu,
F(u8),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Modifiers {
bits: u8,
}
impl Modifiers {
pub const NONE: Self = Self { bits: 0 };
pub const SHIFT: Self = Self { bits: 1 };
pub const CONTROL: Self = Self { bits: 2 };
pub const ALT: Self = Self { bits: 4 };
pub const LOGO: Self = Self { bits: 8 };
pub fn contains(self, other: Self) -> bool {
self.bits & other.bits == other.bits
}
pub fn shift(self) -> bool {
self.contains(Self::SHIFT)
}
pub fn control(self) -> bool {
self.contains(Self::CONTROL)
}
pub fn alt(self) -> bool {
self.contains(Self::ALT)
}
pub fn logo(self) -> bool {
self.contains(Self::LOGO)
}
pub fn command(self) -> bool {
if cfg!(target_os = "macos") {
self.logo()
} else {
self.control()
}
}
}
impl BitOr for Modifiers {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self {
bits: self.bits | other.bits,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Ime<'a> {
Enabled,
Preedit {
text: &'a str,
cursor: Option<(usize, usize)>,
},
Commit(&'a str),
Disabled,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Cursor {
#[default]
Default,
Pointer,
Text,
ResizeColumn,
ResizeRow,
Move,
Grab,
Grabbing,
NotAllowed,
}