use crate::base::Point;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Mods(pub u8);
impl Mods {
pub const NONE: Mods = Mods(0);
pub const SHIFT: Mods = Mods(1);
pub const CTRL: Mods = Mods(2);
pub const ALT: Mods = Mods(4);
pub const SUPER: Mods = Mods(8);
pub const fn union(self, other: Mods) -> Mods {
Mods(self.0 | other.0)
}
pub const fn contains(self, other: Mods) -> bool {
self.0 & other.0 == other.0
}
}
impl std::ops::BitOr for Mods {
type Output = Mods;
fn bitor(self, rhs: Mods) -> Mods {
self.union(rhs)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Key {
Char(char),
Enter,
Escape,
Tab,
Backspace,
Delete,
Insert,
Home,
End,
PageUp,
PageDown,
Up,
Down,
Left,
Right,
F(u8),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct KeyEvent {
pub key: Key,
pub mods: Mods,
}
impl KeyEvent {
pub const fn new(key: Key, mods: Mods) -> Self {
KeyEvent { key, mods }
}
pub const fn plain(key: Key) -> Self {
KeyEvent {
key,
mods: Mods::NONE,
}
}
pub fn chord(self) -> KeyChord {
KeyChord {
key: self.key,
mods: self.mods,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MouseButton {
Left,
Middle,
Right,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MouseKind {
Down(MouseButton),
Up(MouseButton),
Move,
Drag(MouseButton),
ScrollUp,
ScrollDown,
ScrollLeft,
ScrollRight,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct MouseEvent {
pub pos: Point,
pub kind: MouseKind,
pub mods: Mods,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum UiEvent {
Key(KeyEvent),
Mouse(MouseEvent),
FocusIn,
FocusOut,
MouseEnter,
MouseLeave,
Paste(String),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Phase {
Capture,
Target,
Bubble,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct KeyChord {
pub key: Key,
pub mods: Mods,
}
impl KeyChord {
pub const fn new(mods: Mods, key: Key) -> Self {
KeyChord { key, mods }
}
pub fn display(&self) -> String {
let mut out = String::new();
if self.mods.contains(Mods::CTRL) {
out.push_str("Ctrl+");
}
if self.mods.contains(Mods::ALT) {
out.push_str("Alt+");
}
if self.mods.contains(Mods::SHIFT) {
out.push_str("Shift+");
}
match self.key {
Key::Char(' ') => out.push_str("Space"),
Key::Char(c) => out.extend(c.to_uppercase()),
Key::F(n) => out.push_str(&format!("F{n}")),
k => out.push_str(&format!("{k:?}")),
}
out
}
pub const fn plain(key: Key) -> Self {
KeyChord {
key,
mods: Mods::NONE,
}
}
pub const fn ctrl(key: Key) -> Self {
KeyChord {
key,
mods: Mods::CTRL,
}
}
}
#[derive(Default)]
pub struct EventCtx {
pub(crate) stopped: bool,
pub(crate) focus_request: Option<super::tree::ViewId>,
pub(crate) damage_all: bool,
pub(crate) capture_request: Option<Option<super::tree::ViewId>>,
pub(crate) target_rect: crate::base::Rect,
pub(crate) target: Option<super::tree::ViewId>,
pub(crate) current: Option<super::tree::ViewId>,
pub(crate) current_rect: crate::base::Rect,
}
impl EventCtx {
pub fn stop_propagation(&mut self) {
self.stopped = true;
}
pub fn request_focus(&mut self, view: super::tree::ViewId) {
self.focus_request = Some(view);
}
pub fn capture_pointer(&mut self, view: super::tree::ViewId) {
self.capture_request = Some(Some(view));
}
pub fn release_pointer(&mut self) {
self.capture_request = Some(None);
}
pub fn target_rect(&self) -> crate::base::Rect {
self.target_rect
}
pub fn target(&self) -> Option<super::tree::ViewId> {
self.target
}
pub fn current_rect(&self) -> crate::base::Rect {
self.current_rect
}
pub fn current(&self) -> Option<super::tree::ViewId> {
self.current
}
pub fn request_repaint(&mut self) {
self.damage_all = true;
}
}