ruffle/web/src/ui.rs

101 lines
2.7 KiB
Rust
Raw Normal View History

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);
}
}