use winit::dpi::{LogicalSize, PhysicalSize};
use winit::window::{Window, WindowAttributes, Fullscreen};
#[derive(Debug, Clone)]
pub struct WindowConfig {
pub title: String,
pub width: u32,
pub height: u32,
pub fullscreen: bool,
pub resizable: bool,
pub visible: bool,
pub vsync: bool,
pub min_size: Option<(u32, u32)>,
pub max_size: Option<(u32, u32)>,
}
impl Default for WindowConfig {
fn default() -> Self {
Self {
title: "AnvilKit Application".to_string(),
width: 1280,
height: 720,
fullscreen: false,
resizable: true,
visible: true,
vsync: true,
min_size: Some((320, 240)),
max_size: None,
}
}
}
impl WindowConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
self.title = title.into();
self
}
pub fn with_size(mut self, width: u32, height: u32) -> Self {
self.width = width;
self.height = height;
self
}
pub fn with_fullscreen(mut self, fullscreen: bool) -> Self {
self.fullscreen = fullscreen;
self
}
pub fn with_resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
self
}
pub fn with_vsync(mut self, vsync: bool) -> Self {
self.vsync = vsync;
self
}
pub fn with_min_size(mut self, min_size: Option<(u32, u32)>) -> Self {
self.min_size = min_size;
self
}
pub fn with_max_size(mut self, max_size: Option<(u32, u32)>) -> Self {
self.max_size = max_size;
self
}
pub fn to_window_attributes(&self) -> WindowAttributes {
let mut attributes = Window::default_attributes()
.with_title(&self.title)
.with_inner_size(LogicalSize::new(self.width, self.height))
.with_resizable(self.resizable)
.with_visible(self.visible);
if let Some((min_width, min_height)) = self.min_size {
attributes = attributes.with_min_inner_size(LogicalSize::new(min_width, min_height));
}
if let Some((max_width, max_height)) = self.max_size {
attributes = attributes.with_max_inner_size(LogicalSize::new(max_width, max_height));
}
if self.fullscreen {
attributes = attributes.with_fullscreen(Some(Fullscreen::Borderless(None)));
}
attributes
}
}
#[derive(Debug, Clone)]
pub struct WindowState {
size: PhysicalSize<u32>,
scale_factor: f64,
focused: bool,
minimized: bool,
maximized: bool,
fullscreen: bool,
}
impl Default for WindowState {
fn default() -> Self {
Self {
size: PhysicalSize::new(1280, 720),
scale_factor: 1.0,
focused: true,
minimized: false,
maximized: false,
fullscreen: false,
}
}
}
impl WindowState {
pub fn new() -> Self {
Self::default()
}
pub fn size(&self) -> (u32, u32) {
(self.size.width, self.size.height)
}
pub fn set_size(&mut self, width: u32, height: u32) {
self.size = PhysicalSize::new(width, height);
}
pub fn scale_factor(&self) -> f64 {
self.scale_factor
}
pub fn set_scale_factor(&mut self, scale_factor: f64) {
self.scale_factor = scale_factor;
}
pub fn is_focused(&self) -> bool {
self.focused
}
pub fn set_focused(&mut self, focused: bool) {
self.focused = focused;
}
pub fn is_minimized(&self) -> bool {
self.minimized
}
pub fn set_minimized(&mut self, minimized: bool) {
self.minimized = minimized;
}
pub fn is_maximized(&self) -> bool {
self.maximized
}
pub fn set_maximized(&mut self, maximized: bool) {
self.maximized = maximized;
}
pub fn is_fullscreen(&self) -> bool {
self.fullscreen
}
pub fn set_fullscreen(&mut self, fullscreen: bool) {
self.fullscreen = fullscreen;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_window_config_creation() {
let config = WindowConfig::new()
.with_title("Test")
.with_size(800, 600)
.with_fullscreen(true)
.with_resizable(false)
.with_vsync(false);
assert_eq!(config.title, "Test");
assert_eq!(config.width, 800);
assert_eq!(config.height, 600);
assert!(config.fullscreen);
assert!(!config.resizable);
assert!(!config.vsync);
}
#[test]
fn test_window_state_operations() {
let mut state = WindowState::new();
state.set_size(1920, 1080);
assert_eq!(state.size(), (1920, 1080));
state.set_scale_factor(2.0);
assert_eq!(state.scale_factor(), 2.0);
state.set_focused(false);
assert!(!state.is_focused());
state.set_minimized(true);
assert!(state.is_minimized());
state.set_fullscreen(true);
assert!(state.is_fullscreen());
}
#[test]
fn test_window_attributes_conversion() {
let config = WindowConfig::new()
.with_title("Test Window")
.with_size(1024, 768);
let _attributes = config.to_window_attributes();
}
#[test]
fn test_window_config_all_builders() {
let config = WindowConfig::new()
.with_title("Test Window")
.with_size(1920, 1080)
.with_resizable(false)
.with_fullscreen(true)
.with_vsync(false)
.with_min_size(Some((320, 240)))
.with_max_size(Some((3840, 2160)));
assert_eq!(config.title, "Test Window");
assert_eq!(config.width, 1920);
assert_eq!(config.height, 1080);
assert!(!config.resizable);
assert!(config.fullscreen);
assert!(!config.vsync);
assert_eq!(config.min_size, Some((320, 240)));
assert_eq!(config.max_size, Some((3840, 2160)));
}
#[test]
fn test_window_config_default_values() {
let config = WindowConfig::new();
assert_eq!(config.title, "AnvilKit Application");
assert_eq!(config.width, 1280);
assert_eq!(config.height, 720);
assert!(config.resizable);
assert!(!config.fullscreen);
assert!(config.vsync);
}
#[test]
fn test_window_state_set_size() {
let mut state = WindowState::new();
assert_eq!(state.size(), (1280, 720));
state.set_size(1024, 768);
assert_eq!(state.size(), (1024, 768));
}
#[test]
fn test_window_state_scale_factor() {
let mut state = WindowState::new();
assert_eq!(state.scale_factor(), 1.0);
state.set_scale_factor(2.0);
assert_eq!(state.scale_factor(), 2.0);
}
#[test]
fn test_window_state_focus() {
let mut state = WindowState::new();
assert!(state.is_focused());
state.set_focused(false);
assert!(!state.is_focused());
state.set_focused(true);
assert!(state.is_focused());
}
#[test]
fn test_window_state_minimized() {
let mut state = WindowState::new();
assert!(!state.is_minimized());
state.set_minimized(true);
assert!(state.is_minimized());
}
#[test]
fn test_window_state_fullscreen() {
let mut state = WindowState::new();
assert!(!state.is_fullscreen());
state.set_fullscreen(true);
assert!(state.is_fullscreen());
}
}