witas 0.11.2

An asynchronous window library in Rust for Windows
Documentation
use windows::Win32::{
    Foundation::*, Graphics::Direct2D::Common::*, Graphics::Direct2D::*, Graphics::Dxgi::Common::*,
};

#[tokio::main]
async fn main() {
    let mut root_rx = witas::EventReceiver::new();
    let mut inner_rx = witas::EventReceiver::new();
    let root = witas::Window::builder()
        .title("witas inner_window")
        .inner_size(witas::LogicalSize::new(640, 480))
        .set_receiver(&root_rx)
        .await
        .unwrap();
    let inner = witas::InnerWindow::builder(&root)
        .position(witas::LogicalPosition::new(10, 10))
        .size(witas::LogicalSize::new(320, 240))
        .set_receiver(&inner_rx)
        .await
        .unwrap();
    let d2d_factory: ID2D1Factory =
        unsafe { D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, None).unwrap() };
    let render_target = unsafe {
        let size = inner.size().await.unwrap();
        let dpi = inner.dpi().await.unwrap() as f32;
        d2d_factory
            .CreateHwndRenderTarget(
                &D2D1_RENDER_TARGET_PROPERTIES {
                    r#type: D2D1_RENDER_TARGET_TYPE_DEFAULT,
                    pixelFormat: D2D1_PIXEL_FORMAT {
                        format: DXGI_FORMAT_R8G8B8A8_UNORM,
                        alphaMode: D2D1_ALPHA_MODE_UNKNOWN,
                    },
                    dpiX: dpi,
                    dpiY: dpi,
                    ..Default::default()
                },
                &D2D1_HWND_RENDER_TARGET_PROPERTIES {
                    hwnd: HWND(inner.raw_handle() as _),
                    pixelSize: D2D_SIZE_U {
                        width: size.width,
                        height: size.height,
                    },
                    ..Default::default()
                },
            )
            .unwrap()
    };
    let inner_task = tokio::spawn(async move {
        loop {
            let (event, _) = inner_rx.recv().await;
            match event {
                witas::Event::Draw(_) => unsafe {
                    render_target.BeginDraw();
                    let clear_color = D2D1_COLOR_F {
                        r: 0.0,
                        g: 0.0,
                        b: 0.3,
                        a: 0.0,
                    };
                    render_target.Clear(Some(&clear_color));
                    render_target.EndDraw(None, None).unwrap();
                },
                witas::Event::Closed => {
                    println!("inner window closed");
                    break;
                }
                _ => {}
            }
        }
    });
    loop {
        let (event, _) = root_rx.recv().await;
        match event {
            witas::Event::KeyInput(k) => match k.as_vkey_state() {
                (witas::VirtualKey::P, witas::KeyState::Pressed) => {
                    inner.set_position(witas::LogicalPosition::new(50, 50));
                }
                (witas::VirtualKey::S, witas::KeyState::Pressed) => {
                    inner.set_size(witas::LogicalSize::new(100, 100));
                }
                _ => {}
            },
            witas::Event::Closed => {
                println!("root window closed");
                break;
            }
            _ => {}
        }
    }
    inner_task.await.unwrap();
}