use std::path::PathBuf;
use crate::geometry::{Point, Size};
pub(crate) const WHEEL_LINES_PER_DETENT: f32 = 3.0;
pub(crate) const SCROLL_PIXELS_PER_LINE: f32 = 16.0;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MouseButton {
Left,
Right,
Middle,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Key {
Named(NamedKey),
Char(char),
}
impl From<char> for Key {
fn from(c: char) -> Self {
Key::Char(c)
}
}
impl From<NamedKey> for Key {
fn from(named: NamedKey) -> Self {
Key::Named(named)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NamedKey {
Enter,
Backspace,
Delete,
Tab,
Escape,
Space,
Left,
Right,
Up,
Down,
Home,
End,
PageUp,
PageDown,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Modifiers {
pub shift: bool,
pub control: bool,
pub alt: bool,
pub alt_graph: bool,
pub logo: bool,
}
impl Modifiers {
pub fn has_command(&self) -> bool {
if self.alt_graph {
return false;
}
self.control || self.alt || self.logo
}
pub fn mnemonic_alt(&self) -> bool {
self.alt && !self.alt_graph
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DragData {
pub paths: Vec<PathBuf>,
}
impl DragData {
pub fn from_paths(paths: impl IntoIterator<Item = PathBuf>) -> Self {
Self {
paths: paths.into_iter().collect(),
}
}
pub fn has_paths(&self) -> bool {
!self.paths.is_empty()
}
}
#[derive(Clone, Debug)]
pub enum Event {
PointerMove {
pos: Point,
},
PointerDown {
pos: Point,
button: MouseButton,
modifiers: Modifiers,
},
PointerUp {
pos: Point,
button: MouseButton,
modifiers: Modifiers,
},
PointerLeave,
Scroll {
pos: Point,
delta_x: f32,
delta_y: f32,
},
DragEnter {
pos: Point,
},
DragMove {
pos: Point,
},
DragLeave,
Drop {
pos: Point,
data: DragData,
},
KeyDown {
key: Key,
modifiers: Modifiers,
},
KeyUp {
key: Key,
modifiers: Modifiers,
},
Char {
ch: char,
modifiers: Modifiers,
},
Tick,
}
impl Event {
pub fn position(&self) -> Option<Point> {
match self {
Event::PointerMove { pos }
| Event::PointerDown { pos, .. }
| Event::PointerUp { pos, .. }
| Event::Scroll { pos, .. }
| Event::DragEnter { pos, .. }
| Event::DragMove { pos, .. }
| Event::Drop { pos, .. } => Some(*pos),
_ => None,
}
}
pub fn is_keyboard(&self) -> bool {
matches!(
self,
Event::KeyDown { .. } | Event::KeyUp { .. } | Event::Char { .. }
)
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Cursor {
#[default]
Default,
Hand,
Text,
VerticalText,
Crosshair,
Move,
Grab,
Grabbing,
NotAllowed,
NoDrop,
Copy,
Alias,
ContextMenu,
Help,
Progress,
Wait,
Cell,
ZoomIn,
ZoomOut,
AllScroll,
ColResize,
RowResize,
EwResize,
NsResize,
NeswResize,
NwseResize,
}
pub struct EventCtx {
pub(crate) paint_requested: bool,
pub(crate) close_requested: bool,
pub(crate) focus_requested: bool,
pub(crate) focus_released: bool,
pub(crate) consumed: bool,
pub(crate) dismiss_requested: bool,
pub(crate) resize_request: Option<Size>,
pub(crate) drag_request: Option<DragData>,
pub(crate) accepts_drop: bool,
pub(crate) swallow_key: bool,
pub(crate) tick_requested: bool,
pub(crate) focus_next_requested: bool,
pub(crate) cursor_request: Option<Cursor>,
}
impl EventCtx {
pub(crate) fn new() -> Self {
Self {
paint_requested: false,
close_requested: false,
focus_requested: false,
focus_released: false,
consumed: false,
dismiss_requested: false,
resize_request: None,
drag_request: None,
accepts_drop: false,
swallow_key: false,
tick_requested: false,
focus_next_requested: false,
cursor_request: None,
}
}
pub fn is_consumed(&self) -> bool {
self.consumed
}
pub fn consume_event(&mut self) {
self.consumed = true;
}
pub fn swallow_key_until_release(&mut self) {
self.swallow_key = true;
}
pub fn request_paint(&mut self) {
self.paint_requested = true;
}
pub fn request_tick(&mut self) {
self.tick_requested = true;
}
pub fn close(&mut self) {
self.close_requested = true;
}
pub fn is_focus_requested(&self) -> bool {
self.focus_requested
}
pub fn is_focus_released(&self) -> bool {
self.focus_released
}
pub fn clear_focus_flags(&mut self) {
self.focus_requested = false;
self.focus_released = false;
}
pub fn request_focus(&mut self) {
self.focus_requested = true;
self.focus_released = false;
}
pub fn release_focus(&mut self) {
self.focus_released = true;
self.focus_requested = false;
}
pub fn request_focus_next(&mut self) {
self.focus_next_requested = true;
}
pub fn is_focus_next_requested(&self) -> bool {
self.focus_next_requested
}
pub fn request_dismiss(&mut self) {
self.dismiss_requested = true;
}
pub fn is_dismiss_requested(&self) -> bool {
self.dismiss_requested
}
pub fn request_window_size(&mut self, width: i32, height: i32) {
self.resize_request = Some(Size::new(width.max(1), height.max(1)));
}
pub fn start_drag(&mut self, data: DragData) {
self.drag_request = Some(data);
}
pub fn accept_drop(&mut self) {
self.accepts_drop = true;
}
pub fn set_cursor(&mut self, cursor: Cursor) {
self.cursor_request = Some(cursor);
}
}