use std::fmt;
use std::rc::Rc;
use std::time::Duration;
pub use raw_window_handle::RawWindowHandle;
use crate::{Rect, ViewRef};
#[derive(Clone, Debug, PartialEq)]
pub struct WindowConfig {
pub title: String,
pub size: [f64; 2],
pub position: Option<[f64; 2]>,
pub decorations: bool,
pub resizable: bool,
pub level: WindowLevel,
pub activating: bool,
pub all_desktops: bool,
pub background: WindowBackground,
pub shadow: bool,
pub visible: bool,
}
impl Default for WindowConfig {
fn default() -> WindowConfig {
WindowConfig {
title: String::new(),
size: [900.0, 600.0],
position: None,
decorations: true,
resizable: true,
level: WindowLevel::Normal,
activating: true,
all_desktops: false,
background: WindowBackground::Solid,
shadow: true,
visible: true,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum WindowLevel {
#[default]
Normal,
AlwaysOnTop,
AlwaysOnBottom,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum WindowBackground {
#[default]
Solid,
Transparent,
Blurred,
Glass,
}
impl WindowBackground {
pub fn sees_through(self) -> bool {
self != WindowBackground::Solid
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct RequestId(pub u64);
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ViewError {
Unsupported,
Failed(String),
}
impl fmt::Display for ViewError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ViewError::Unsupported => f.write_str("the platform makes no views on request"),
ViewError::Failed(reason) => {
write!(f, "the platform could not make the view: {reason}")
}
}
}
}
impl std::error::Error for ViewError {}
pub type WindowRef = Rc<dyn HostWindow>;
pub trait HostWindow: 'static {
fn view(&self) -> ViewRef;
fn frame(&self) -> Rect;
fn set_frame(&self, frame: Rect, animate: Option<Duration>);
fn set_title(&self, title: &str);
fn show(&self);
fn hide(&self);
fn is_minimized(&self) -> bool;
fn is_occluded(&self) -> bool;
fn close(&self);
fn native_handle(&self) -> Option<RawWindowHandle>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_default_window_is_an_ordinary_visible_one() {
let config = WindowConfig::default();
assert!(config.decorations && config.visible && config.activating);
assert_eq!(config.level, WindowLevel::Normal);
assert_eq!(config.background, WindowBackground::Solid);
}
#[test]
fn every_background_but_solid_sees_through() {
assert!(!WindowBackground::Solid.sees_through());
assert!(WindowBackground::Transparent.sees_through());
assert!(WindowBackground::Blurred.sees_through());
assert!(WindowBackground::Glass.sees_through());
}
}