use blinc_platform::{Cursor, Window, WindowId};
#[derive(Debug)]
pub struct WebWindow {
#[cfg(target_arch = "wasm32")]
canvas: web_sys::HtmlCanvasElement,
logical_width: f32,
logical_height: f32,
scale_factor: f64,
}
unsafe impl Send for WebWindow {}
unsafe impl Sync for WebWindow {}
impl WebWindow {
#[cfg(target_arch = "wasm32")]
pub fn from_canvas(canvas: web_sys::HtmlCanvasElement) -> Self {
let logical_width = canvas.client_width() as f32;
let logical_height = canvas.client_height() as f32;
let scale_factor = web_sys::window()
.map(|w| w.device_pixel_ratio())
.unwrap_or(1.0);
Self {
canvas,
logical_width,
logical_height,
scale_factor,
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn placeholder() -> Self {
Self {
logical_width: 0.0,
logical_height: 0.0,
scale_factor: 1.0,
}
}
#[cfg(target_arch = "wasm32")]
pub fn refresh_dimensions(&mut self) {
self.logical_width = self.canvas.client_width() as f32;
self.logical_height = self.canvas.client_height() as f32;
if let Some(w) = web_sys::window() {
self.scale_factor = w.device_pixel_ratio();
}
}
#[cfg(target_arch = "wasm32")]
pub fn resize_to_logical(&mut self, logical_width: f32, logical_height: f32) {
self.logical_width = logical_width;
self.logical_height = logical_height;
let physical_w = (logical_width * self.scale_factor as f32).round() as u32;
let physical_h = (logical_height * self.scale_factor as f32).round() as u32;
self.canvas.set_width(physical_w);
self.canvas.set_height(physical_h);
}
#[cfg(target_arch = "wasm32")]
pub fn canvas(&self) -> &web_sys::HtmlCanvasElement {
&self.canvas
}
}
impl Window for WebWindow {
fn id(&self) -> WindowId {
WindowId::PRIMARY
}
fn size(&self) -> (u32, u32) {
let physical_w = (self.logical_width * self.scale_factor as f32).round() as u32;
let physical_h = (self.logical_height * self.scale_factor as f32).round() as u32;
(physical_w, physical_h)
}
fn logical_size(&self) -> (f32, f32) {
(self.logical_width, self.logical_height)
}
fn scale_factor(&self) -> f64 {
self.scale_factor
}
fn set_title(&self, title: &str) {
#[cfg(target_arch = "wasm32")]
if let Some(doc) = web_sys::window().and_then(|w| w.document()) {
doc.set_title(title);
}
#[cfg(not(target_arch = "wasm32"))]
let _ = title;
}
fn set_cursor(&self, cursor: Cursor) {
#[cfg(target_arch = "wasm32")]
{
let css = match cursor {
Cursor::Default => "default",
Cursor::Pointer => "pointer",
Cursor::Text => "text",
Cursor::Crosshair => "crosshair",
Cursor::Move => "move",
Cursor::NotAllowed => "not-allowed",
Cursor::ResizeNS => "ns-resize",
Cursor::ResizeEW => "ew-resize",
Cursor::ResizeNESW => "nesw-resize",
Cursor::ResizeNWSE => "nwse-resize",
Cursor::Grab => "grab",
Cursor::Grabbing => "grabbing",
Cursor::Wait => "wait",
Cursor::Progress => "progress",
Cursor::None => "none",
};
let _ = self.canvas.style().set_property("cursor", css);
}
#[cfg(not(target_arch = "wasm32"))]
let _ = cursor;
}
fn request_redraw(&self) {
}
fn is_focused(&self) -> bool {
#[cfg(target_arch = "wasm32")]
{
web_sys::window()
.and_then(|w| w.document())
.map(|d| d.has_focus().unwrap_or(true))
.unwrap_or(true)
}
#[cfg(not(target_arch = "wasm32"))]
{
true
}
}
fn is_visible(&self) -> bool {
#[cfg(target_arch = "wasm32")]
{
web_sys::window()
.and_then(|w| w.document())
.map(|d| d.visibility_state() == web_sys::VisibilityState::Visible)
.unwrap_or(true)
}
#[cfg(not(target_arch = "wasm32"))]
{
false
}
}
fn safe_area_insets(&self) -> (f32, f32, f32, f32) {
(0.0, 0.0, 0.0, 0.0)
}
}