Skip to main content

iris_core/
window.rs

1//! 跨平台窗口管理
2//!
3//! 桌面端基于 winit 0.30+,Wasm 端基于浏览器 canvas(待实现)。
4
5#![allow(missing_docs)]
6
7/// 窗口创建配置。
8#[derive(Debug, Clone)]
9pub struct WindowConfig {
10    /// 窗口标题。
11    pub title: String,
12    /// 窗口初始宽度(逻辑像素)。
13    pub width: u32,
14    /// 窗口初始高度(逻辑像素)。
15    pub height: u32,
16    /// 是否允许调整窗口大小。
17    pub resizable: bool,
18    /// 是否最大化显示。
19    pub maximized: bool,
20}
21
22impl Default for WindowConfig {
23    fn default() -> Self {
24        Self {
25            title: "Iris App".to_string(),
26            width: 1280,
27            height: 720,
28            resizable: true,
29            maximized: false,
30        }
31    }
32}
33
34impl WindowConfig {
35    /// 快速创建指定标题和尺寸的窗口配置。
36    pub fn new(title: impl Into<String>, width: u32, height: u32) -> Self {
37        Self {
38            title: title.into(),
39            width,
40            height,
41            ..Default::default()
42        }
43    }
44}
45
46/// 在桌面端创建 winit 窗口。
47#[cfg(not(target_arch = "wasm32"))]
48pub fn create_window(
49    event_loop: &winit::event_loop::ActiveEventLoop,
50    config: WindowConfig,
51) -> Result<winit::window::Window, Box<dyn std::error::Error>> {
52    use winit::dpi::LogicalSize;
53
54    let attributes = winit::window::Window::default_attributes()
55        .with_title(config.title)
56        .with_inner_size(LogicalSize::new(config.width, config.height))
57        .with_resizable(config.resizable)
58        .with_maximized(config.maximized);
59
60    let window = event_loop.create_window(attributes)?;
61    Ok(window)
62}
63
64/// Wasm 窗口创建:通过 wasm-bindgen 获取 canvas 并返回窗口 ID。
65/// 返回 canvas 元素 ID 字符串,由上层 iris-gpu 初始化 WebGPU 上下文。
66#[cfg(target_arch = "wasm32")]
67pub fn create_window(
68    _event_loop: &(),
69    config: WindowConfig,
70) -> Result<String, Box<dyn std::error::Error>> {
71    use wasm_bindgen::JsCast;
72
73    let window = web_sys::window().ok_or("No browser window found")?;
74    let document = window.document().ok_or("No document found")?;
75
76    // 创建 canvas 元素
77    let canvas = document.create_element("canvas")
78        .map_err(|_| "Failed to create canvas element")?;
79    let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>()
80        .map_err(|_| "Failed to cast to HtmlCanvasElement")?;
81
82    canvas.set_width(config.width);
83    canvas.set_height(config.height);
84    canvas.set_attribute("style", "display:block;width:100%;height:100%")
85        .ok();
86
87    // 插入到 body
88    let body = document.body().ok_or("No body element")?;
89    body.append_child(&canvas)
90        .map_err(|_| "Failed to append canvas")?;
91
92    // 设置标题
93    document.set_title(&config.title);
94
95    let canvas_id = canvas.id();
96    Ok(canvas_id)
97}