use super::JavascriptPlayer; use ruffle_core::backend::ui::{Error, MouseCursor, UiBackend}; use ruffle_web_common::JsResult; use web_sys::HtmlCanvasElement; #[derive(Debug)] struct FullScreenError { jsval: String, } impl std::fmt::Display for FullScreenError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.jsval) } } impl std::error::Error for FullScreenError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } /// An implementation of `UiBackend` utilizing `web_sys` bindings to input APIs. pub struct WebUiBackend { js_player: JavascriptPlayer, canvas: HtmlCanvasElement, cursor_visible: bool, cursor: MouseCursor, } impl WebUiBackend { pub fn new(js_player: JavascriptPlayer, canvas: &HtmlCanvasElement) -> Self { Self { js_player, canvas: canvas.clone(), cursor_visible: true, cursor: MouseCursor::Arrow, } } fn update_mouse_cursor(&self) { let cursor = if self.cursor_visible { match self.cursor { MouseCursor::Arrow => "auto", MouseCursor::Hand => "pointer", MouseCursor::IBeam => "text", MouseCursor::Grab => "grab", } } else { "none" }; self.canvas .style() .set_property("cursor", cursor) .warn_on_error(); } } impl UiBackend for WebUiBackend { fn mouse_visible(&self) -> bool { self.cursor_visible } fn set_mouse_visible(&mut self, visible: bool) { self.cursor_visible = visible; self.update_mouse_cursor(); } fn set_mouse_cursor(&mut self, cursor: MouseCursor) { self.cursor = cursor; self.update_mouse_cursor(); } fn set_clipboard_content(&mut self, _content: String) { log::warn!("set clipboard not implemented"); } fn set_fullscreen(&mut self, is_full: bool) -> Result<(), Error> { match self.js_player.set_fullscreen(is_full) { Ok(_) => Ok(()), Err(jsval) => Err(Box::new(FullScreenError { jsval: jsval .as_string() .unwrap_or_else(|| "Failed to change full screen state".to_string()), })), } } fn display_unsupported_message(&self) { self.js_player.display_unsupported_message() } fn display_root_movie_download_failed_message(&self) { self.js_player.display_root_movie_download_failed_message() } fn message(&self, message: &str) { self.js_player.display_message(message); } }