use crate::geometry::Point;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MouseButton {
Left,
Right,
Middle,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WindowOp {
Minimize,
ToggleMaximize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum CursorShape {
#[default]
Arrow,
Hand,
Text,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PointerKind {
Down,
Up,
Move,
Enter,
Leave,
Wheel(i32),
}
#[derive(Debug, Clone, Copy)]
pub struct PointerEvent {
pub kind: PointerKind,
pub pos: Point,
pub button: MouseButton,
pub click_count: u8,
}
impl PointerEvent {
pub fn single(kind: PointerKind, pos: Point, button: MouseButton) -> Self {
Self {
kind,
pos,
button,
click_count: 1,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Key {
Tab,
Enter,
Escape,
Backspace,
Delete,
Space,
Left,
Right,
Up,
Down,
Home,
End,
Char(char),
Other(u32),
}
#[derive(Debug, Clone, Copy)]
pub struct KeyEvent {
pub key: Key,
pub pressed: bool,
pub shift: bool,
pub ctrl: bool,
}
#[derive(Debug, Clone, Copy)]
pub enum Event {
Pointer(PointerEvent),
Key(KeyEvent),
}
#[derive(Clone)]
pub enum MenuAction {
SendKey(KeyEvent),
Run(std::rc::Rc<dyn Fn()>),
}
#[derive(Clone)]
pub struct MenuItem {
pub label: String,
pub action: MenuAction,
pub enabled: bool,
pub checked: bool,
pub icon: Option<String>,
pub shortcut: Option<String>,
pub separator: bool,
pub submenu: Vec<MenuItem>,
}
fn noop_action() -> MenuAction {
MenuAction::Run(std::rc::Rc::new(|| {}))
}
impl MenuItem {
pub fn key(label: impl Into<String>, key: KeyEvent, enabled: bool) -> Self {
Self {
label: label.into(),
action: MenuAction::SendKey(key),
enabled,
checked: false,
icon: None,
shortcut: None,
separator: false,
submenu: Vec::new(),
}
}
pub fn run(label: impl Into<String>, f: impl Fn() + 'static, checked: bool) -> Self {
Self {
label: label.into(),
action: MenuAction::Run(std::rc::Rc::new(f)),
enabled: true,
checked,
icon: None,
shortcut: None,
separator: false,
submenu: Vec::new(),
}
}
pub fn separator() -> Self {
Self {
label: String::new(),
action: noop_action(),
enabled: false,
checked: false,
icon: None,
shortcut: None,
separator: true,
submenu: Vec::new(),
}
}
pub fn submenu(label: impl Into<String>, items: Vec<MenuItem>) -> Self {
Self {
label: label.into(),
action: noop_action(),
enabled: true,
checked: false,
icon: None,
shortcut: None,
separator: false,
submenu: items,
}
}
pub fn with_icon(mut self, icon: impl Into<String>) -> Self {
self.icon = Some(icon.into());
self
}
pub fn with_shortcut(mut self, s: impl Into<String>) -> Self {
self.shortcut = Some(s.into());
self
}
pub fn with_check(mut self, checked: bool) -> Self {
self.checked = checked;
self
}
pub fn is_actionable(&self) -> bool {
!self.separator && self.submenu.is_empty() && self.enabled
}
}
#[derive(Clone)]
pub struct MenuRequest {
pub pos: Point,
pub items: Vec<MenuItem>,
pub min_width: i32,
}