xloop_types 0.1.1

core types for xloop.
Documentation
mod metas;
pub use metas::Metas;
mod key;
pub use key::{Key, UnrecognizedKeyError};
mod code;
pub use code::{Code, UnrecognizedCodeError};
mod location;
pub use location::Location;

pub extern crate raw_window_handle as raw;

pub mod prelude {
	pub use super::AppDelegate as _;
	pub use super::AppHandle as _;
	pub use super::AppProxy as _;
	pub use super::AppRef as _;
	pub use super::IntoEvt as _;
	pub use super::Platform as _;
	pub use super::WinDelegate as _;
	pub use super::WinHandle as _;
	pub use super::WinRef as _;
}

pub trait Platform: Sized + 'static {
	type Error: std::error::Error;
	type AppRef<'a>: AppRef<Self> + Copy;
	type AppHandle: AppHandle<Self>;
	type AppProxy: AppProxy;
	type WinRef<'a>: WinRef<Self> + Copy;
	type WinHandle: WinHandle<Self>;
	type WinRaw: raw::HasWindowHandle + raw::HasDisplayHandle + Send + Sync;
	type EvtMouse<'a>: IntoEvt<Self, EvtMouse>;
	type EvtWheel<'a>: IntoEvt<Self, EvtWheel>;
	type EvtKey<'a>: IntoEvt<Self, EvtKey>;
	type EvtTouch<'a>: IntoEvt<Self, EvtTouch>;
	type EvtCommit<'a>: IntoEvt<Self, EvtCommit>;
	fn run(delegate: impl AppDelegate<Self>) -> Result<Option<Self::AppHandle>, Self::Error>;
	fn win(key: impl AsRef<str>, delegate: impl WinDelegate<Self>) -> Result<Self::WinHandle, Self::Error>;
	fn log(level: log::LevelFilter);
	fn read(path: impl AsRef<std::path::Path>) -> Option<Vec<u8>>;
	// TODO 配置信息
	// TODO delay 屏幕,菜单
}

mod app {
	use super::Platform;
	pub trait AppDelegate<P: Platform>: 'static {
		fn on_launch(&self, _: P::AppRef<'_>) {}
		fn on_terminate(&self, _: P::AppRef<'_>) {}
	}
	pub trait AppRef<P: Platform> {
		fn terminate(&self);
		fn proxy(&self) -> Option<P::AppProxy>;
	}
	pub trait AppHandle<P: Platform>: Sized {
		fn singleton() -> Option<Self>;
		fn with(&self, _: impl FnMut(P::AppRef<'_>));
	}
	pub trait AppProxy: Sized + Send + Sync + 'static {
		fn wake(&self, id: i64);
		fn to_waker(self, id: i64) -> core::task::Waker {
			struct AppWaker<T: AppProxy>(T, i64);
			impl<T: AppProxy> std::task::Wake for AppWaker<T> {
				fn wake(self: std::sync::Arc<Self>) {
					self.0.wake(self.1);
				}
			}
			std::sync::Arc::new(AppWaker(self, id)).into()
		}
	}
}
pub use app::*;

mod win {
	use super::Platform;
	pub trait WinDelegate<P: Platform>: 'static {
		fn on_create(&self, _: P::WinRef<'_>) {}
		fn on_start(&self, _: P::WinRef<'_>) {} // visible
		fn on_resume(&self, _: P::WinRef<'_>) {} // gain focus

		fn on_pause(&self, _: P::WinRef<'_>) {} // covered by another lost focus
		fn on_stop(&self, _: P::WinRef<'_>) {} // no longer visible
		fn on_destroy(&self, _: P::WinRef<'_>) {}

		fn req_close(&self, _: P::WinRef<'_>) -> bool {
			true
		}

		fn on_proxy(&self, _: P::WinRef<'_>, _: i64) {}

		fn on_resize(&self, _: P::WinRef<'_>, _size: (u32, u32)) {}

		fn req_draw(&self, _: P::WinRef<'_>, _nanos: i64) {}

		fn on_mouse(&self, _: P::WinRef<'_>, _evt: P::EvtMouse<'_>) -> bool {
			false
		}
		fn on_touch(&self, _: P::WinRef<'_>, _evt: P::EvtTouch<'_>) -> bool {
			false
		}
		fn on_wheel(&self, _: P::WinRef<'_>, _evt: P::EvtWheel<'_>) -> bool {
			false
		}
		fn on_key(&self, _: P::WinRef<'_>, _evt: P::EvtKey<'_>) -> bool {
			false
		}
		fn on_commit(&self, _: P::WinRef<'_>, _evt: P::EvtCommit<'_>) -> bool {
			false
		}
	}
	pub trait WinRef<P: Platform> {
		fn raw(&self) -> Option<P::WinRaw>;
		fn size(&self) -> (u32, u32);
		fn density(&self) -> f32;
		fn fresh(&self, _: &str);
		fn close(&self);
		fn show(&self);
	}
	pub trait WinHandle<P: Platform>: Sized {
		fn with(&self, _: impl FnMut(P::WinRef<'_>));
	}
}
pub use win::*;

pub trait IntoEvt<P: Platform, T> {
	fn to_evt(&self, win: P::WinRef<'_>) -> Option<T>;
}
mod evt_mouse {
	use crate::Metas;
	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
	pub enum Button {
		Left,
		Middle,
		Right,
		Mouse(u8),
		Touch(u8),
	}
	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
	pub enum Phase {
		Start,
		End,
		Update,
		Cancel,
	}
	#[derive(Debug, Clone)]
	pub struct EvtMouse {
		pub button: Button,
		pub phase: Phase,
		pub point: (f32, f32),
		pub metas: Metas,
	}
	impl EvtMouse {
		pub fn new(button: Button, phase: Phase, point: (f32, f32), metas: Metas) -> Self {
			Self {
				button,
				phase,
				point,
				metas,
			}
		}
	}
	#[derive(Debug, Clone)]
	pub struct EvtTouch {
		pub mouse: EvtMouse,
		pub force: u32,
	}
	impl EvtTouch {
		pub fn new(mouse: EvtMouse, force: u32) -> Self {
			Self { mouse, force }
		}
	}
}
pub use evt_mouse::*;

mod evt_wheel {
	#[derive(Debug, Clone)]
	pub enum EvtWheel {
		Pixel(f32, f32, f32),
		Line(f32, f32, f32),
		Page(f32, f32, f32),
	}
}
pub use evt_wheel::*;

mod evt_key {
	use crate::{Code, Key, Location, Metas};
	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
	pub enum State {
		Down,
		Up,
	}
	#[derive(Debug, Clone)]
	pub struct EvtKey {
		pub key: Key,
		pub code: Code,
		pub state: State,
		pub location: Location,
		pub metas: Metas,
		pub repeat: bool,
		pub composing: bool,
	}
	impl EvtKey {
		pub fn new(key: Key, code: Code, state: State, location: Location, metas: Metas, repeat: bool, composing: bool) -> Self {
			Self {
				key,
				code,
				state,
				location,
				metas,
				repeat,
				composing,
			}
		}
	}
	impl From<Code> for Location {
		fn from(code: Code) -> Self {
			use Code as KeyCode;
			use Location as KeyLocation;
			match code {
				KeyCode::MetaRight => KeyLocation::Right,
				KeyCode::MetaLeft => KeyLocation::Left,
				KeyCode::ShiftLeft => KeyLocation::Left,
				KeyCode::AltLeft => KeyLocation::Left,
				KeyCode::ControlLeft => KeyLocation::Left,
				KeyCode::ShiftRight => KeyLocation::Right,
				KeyCode::AltRight => KeyLocation::Right,
				KeyCode::ControlRight => KeyLocation::Right,

				KeyCode::NumLock => KeyLocation::Numpad,
				KeyCode::NumpadDecimal => KeyLocation::Numpad,
				KeyCode::NumpadMultiply => KeyLocation::Numpad,
				KeyCode::NumpadAdd => KeyLocation::Numpad,
				KeyCode::NumpadDivide => KeyLocation::Numpad,
				KeyCode::NumpadEnter => KeyLocation::Numpad,
				KeyCode::NumpadSubtract => KeyLocation::Numpad,
				KeyCode::NumpadEqual => KeyLocation::Numpad,
				KeyCode::Numpad0 => KeyLocation::Numpad,
				KeyCode::Numpad1 => KeyLocation::Numpad,
				KeyCode::Numpad2 => KeyLocation::Numpad,
				KeyCode::Numpad3 => KeyLocation::Numpad,
				KeyCode::Numpad4 => KeyLocation::Numpad,
				KeyCode::Numpad5 => KeyLocation::Numpad,
				KeyCode::Numpad6 => KeyLocation::Numpad,
				KeyCode::Numpad7 => KeyLocation::Numpad,
				KeyCode::Numpad8 => KeyLocation::Numpad,
				KeyCode::Numpad9 => KeyLocation::Numpad,

				_ => KeyLocation::Standard,
			}
		}
	}
	impl From<Code> for Key {
		fn from(code: Code) -> Self {
			type KeyCode = Code;
			type NamedKey = Key;
			match code {
				KeyCode::Enter => NamedKey::Enter,
				KeyCode::Tab => NamedKey::Tab,
				KeyCode::Space => NamedKey::Character(" ".into()),
				KeyCode::Backspace => NamedKey::Backspace,
				KeyCode::Escape => NamedKey::Escape,
				KeyCode::MetaRight => NamedKey::Super,
				KeyCode::MetaLeft => NamedKey::Super,
				KeyCode::ShiftLeft => NamedKey::Shift,
				KeyCode::AltLeft => NamedKey::Alt,
				KeyCode::ControlLeft => NamedKey::Control,
				KeyCode::ShiftRight => NamedKey::Shift,
				KeyCode::AltRight => NamedKey::Alt,
				KeyCode::ControlRight => NamedKey::Control,

				KeyCode::NumLock => NamedKey::NumLock,
				KeyCode::AudioVolumeUp => NamedKey::AudioVolumeUp,
				KeyCode::AudioVolumeDown => NamedKey::AudioVolumeDown,

				KeyCode::NumpadEnter => NamedKey::Enter,

				KeyCode::F1 => NamedKey::F1,
				KeyCode::F2 => NamedKey::F2,
				KeyCode::F3 => NamedKey::F3,
				KeyCode::F4 => NamedKey::F4,
				KeyCode::F5 => NamedKey::F5,
				KeyCode::F6 => NamedKey::F6,
				KeyCode::F7 => NamedKey::F7,
				KeyCode::F8 => NamedKey::F8,
				KeyCode::F9 => NamedKey::F9,
				KeyCode::F10 => NamedKey::F10,
				KeyCode::F11 => NamedKey::F11,
				KeyCode::F12 => NamedKey::F12,
				KeyCode::F13 => NamedKey::F13,
				KeyCode::F14 => NamedKey::F14,
				KeyCode::F15 => NamedKey::F15,
				KeyCode::F16 => NamedKey::F16,
				KeyCode::F17 => NamedKey::F17,
				KeyCode::F18 => NamedKey::F18,
				KeyCode::F19 => NamedKey::F19,
				KeyCode::F20 => NamedKey::F20,

				KeyCode::Insert => NamedKey::Insert,
				KeyCode::Home => NamedKey::Home,
				KeyCode::PageUp => NamedKey::PageUp,
				KeyCode::Delete => NamedKey::Delete,
				KeyCode::End => NamedKey::End,
				KeyCode::PageDown => NamedKey::PageDown,
				KeyCode::ArrowLeft => NamedKey::ArrowLeft,
				KeyCode::ArrowRight => NamedKey::ArrowRight,
				KeyCode::ArrowDown => NamedKey::ArrowDown,
				KeyCode::ArrowUp => NamedKey::ArrowUp,
				_ => NamedKey::Unidentified(0),
			}
		}
	}
}
pub use evt_key::*;
mod evt_commit {
	use std::borrow::Cow;

	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
	pub enum Action {
		Begin,
		Update,
		End,
		Back,
	}
	#[derive(Debug, Clone)]
	pub struct EvtCommit {
		pub action: Action,
		pub data: Option<Cow<'static, str>>,
	}
	impl EvtCommit {
		pub fn new(action: Action, data: Option<Cow<'static, str>>) -> Self {
			Self { action, data }
		}
		pub fn begin() -> Self {
			Self::new(Action::Begin, None)
		}
		pub fn update(data: Cow<'static, str>) -> Self {
			Self::new(Action::Update, Some(data))
		}
		pub fn end(data: Cow<'static, str>) -> Self {
			Self::new(Action::End, Some(data))
		}
		pub fn back() -> Self {
			Self::new(Action::Back, None)
		}
	}
	impl<P: super::Platform> super::IntoEvt<P, EvtCommit> for &EvtCommit {
		fn to_evt(&self, _: <P as crate::Platform>::WinRef<'_>) -> Option<EvtCommit> {
			Some((*self).clone())
		}
	}
}
pub use evt_commit::*;