#[cfg(target_os = "windows")]
pub mod win32;
use std::any::Any;
use serde::{Deserialize, Serialize};
type Error = super::Error;
pub struct AppInfo {
pub name: String,
pub window: bool,
pub num_buffers: u32,
pub dpi_aware: bool,
}
pub enum MouseButton {
Left,
Middle,
Right,
X1,
X2,
Count,
}
pub enum SysKey {
Ctrl,
Shift,
Alt,
Count
}
pub enum Key {
Tab,
Left,
Right,
Up,
Down,
PageUp,
PageDown,
Home,
End,
Insert,
Delete,
Backspace,
Space,
Enter,
Escape,
KeyPadEnter,
}
#[derive(Eq, PartialEq)]
pub enum Cursor {
None,
Arrow,
TextInput,
ResizeAll,
ResizeEW,
ResizeNS,
ResizeNESW,
ResizeNWSE,
Hand,
NotAllowed,
}
#[derive(Clone)]
pub struct MonitorInfo {
pub rect: Rect<i32>,
pub client_rect: Rect<i32>,
pub dpi_scale: f32,
pub primary: bool,
}
#[derive(Copy, Clone, Serialize, Deserialize, PartialEq)]
pub struct Rect<T> {
pub x: T,
pub y: T,
pub width: T,
pub height: T,
}
#[derive(Copy, Clone)]
pub struct Point<T> {
pub x: T,
pub y: T,
}
pub type Size<T> = Point<T>;
bitflags! {
pub struct WindowStyleFlags: u32 {
const NONE = 0;
const VISIBLE = 1<<0;
const POPUP = 1<<1;
const OVERLAPPED_WINDOW = 1<<2;
const TOOL_WINDOW = 1<<3;
const APP_WINDOW = 1<<4;
const TOPMOST = 1<<5;
const IMGUI = 1<<6;
}
pub struct WindowEventFlags : u32 {
const NONE = 0;
const CLOSE = 1<<0;
const MOVE = 1<<1;
const SIZE = 1<<2;
}
pub struct OpenFileDialogFlags : u32 {
const FILES = 1<<0;
const FOLDERS = 1<<1;
const MULTI_SELECT = 1<<2;
}
}
#[derive(Clone)]
pub struct WindowInfo<A: App> {
pub title: String,
pub rect: Rect<i32>,
pub style: WindowStyleFlags,
pub parent_handle: Option<A::NativeHandle>,
}
pub trait NativeHandle<A: App> {
fn get_isize(&self) -> isize;
fn copy(&self) -> Self;
}
pub trait App: 'static + Any + Sized + Send + Sync + Clone {
type Window: Window<Self>;
type NativeHandle: NativeHandle<Self>;
fn create(info: AppInfo) -> Self;
fn create_window(&mut self, info: WindowInfo<Self>) -> Self::Window;
fn destroy_window(&mut self, window: &Self::Window);
fn run(&mut self) -> bool;
fn exit(&mut self, exit_code: i32);
fn get_mouse_pos(&self) -> Point<i32>;
fn get_mouse_wheel(&self) -> f32;
fn get_mouse_hwheel(&self) -> f32;
fn get_mouse_buttons(&self) -> [bool; MouseButton::Count as usize];
fn get_mouse_pos_delta(&self) -> Size<i32>;
fn get_utf16_input(&self) -> Vec<u16>;
fn get_keys_down(&self) -> [bool; 256];
fn get_keys_pressed(&self) -> [bool; 256];
fn is_sys_key_down(&self, key: SysKey) -> bool;
fn is_sys_key_pressed(&self, key: SysKey) -> bool;
fn get_key_code(key: Key) -> i32;
fn set_input_enabled(&mut self, keyboard: bool, mouse: bool);
fn get_input_enabled(&self) -> (bool, bool);
fn enumerate_display_monitors() -> Vec<MonitorInfo>;
fn set_cursor(&self, cursor: &Cursor);
fn open_file_dialog(flags: OpenFileDialogFlags, exts: Vec<&str>) -> Result<Vec<String>, Error>;
fn get_console_window_rect(&self) -> Rect<i32>;
fn set_console_window_rect(&self, rect: Rect<i32>);
}
pub trait Window<A: App>: 'static + Send + Sync + Any + Sized + Clone {
fn bring_to_front(&self);
fn show(&self, show: bool, activate: bool);
fn update(&mut self, app: &mut A);
fn close(&mut self);
fn update_style(&mut self, flags: WindowStyleFlags, rect: Rect<i32>);
fn is_focused(&self) -> bool;
fn is_minimised(&self) -> bool;
fn set_focused(&self);
fn is_mouse_hovered(&self) -> bool;
fn set_title(&self, title: String);
fn set_pos(&self, pos: Point<i32>);
fn set_size(&self, size: Size<i32>);
fn get_pos(&self) -> Point<i32>;
fn get_viewport_rect(&self) -> Rect<i32>;
fn get_size(&self) -> Size<i32>;
fn get_window_rect(&self) -> Rect<i32>;
fn get_mouse_client_pos(&self, mouse_pos: Point<i32>) -> Point<i32>;
fn get_dpi_scale(&self) -> f32;
fn get_native_handle(&self) -> A::NativeHandle;
fn get_events(&self) -> WindowEventFlags;
fn clear_events(&mut self);
fn as_ptr(&self) -> *const Self;
fn as_mut_ptr(&mut self) -> *mut Self;
}
impl Default for Point<f32> {
fn default() -> Self {
Point::<f32> { x: 0.0, y: 0.0 }
}
}
impl Default for Point<i32> {
fn default() -> Self {
Point::<i32> { x: 0, y: 0 }
}
}
impl Default for Point<u32> {
fn default() -> Self {
Point::<u32> { x: 0, y: 0 }
}
}
impl<A> Default for WindowInfo<A> where A: App {
fn default() -> Self {
Self {
title: "hotline".to_string(),
rect: Rect {
x: 100,
y: 100,
width: 1280,
height: 720,
},
style: WindowStyleFlags::NONE,
parent_handle: None,
}
}
}