On Web, implement and fix missing methods on Window(Builder) (#2949)

This commit is contained in:
daxpedda 2023-07-11 13:14:40 +02:00 committed by GitHub
parent 50b17a3907
commit 3b2d1a7643
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 168 additions and 61 deletions

View file

@ -88,21 +88,46 @@ impl Canvas {
// this can't fail: we aren't using a pseudo-element
.expect("Invalid pseudo-element");
let common = Common {
window,
document,
raw: canvas,
style,
old_size: Rc::default(),
current_size: Rc::default(),
wants_fullscreen: Rc::new(RefCell::new(false)),
};
if let Some(size) = attr.inner_size {
let size = size.to_logical(super::scale_factor(&window));
super::set_canvas_size(&document, &canvas, &style, size);
let size = size.to_logical(super::scale_factor(&common.window));
super::set_canvas_size(&common.document, &common.raw, &common.style, size);
}
if let Some(size) = attr.min_inner_size {
let size = size.to_logical(super::scale_factor(&common.window));
super::set_canvas_min_size(&common.document, &common.raw, &common.style, Some(size));
}
if let Some(size) = attr.max_inner_size {
let size = size.to_logical(super::scale_factor(&common.window));
super::set_canvas_max_size(&common.document, &common.raw, &common.style, Some(size));
}
if let Some(position) = attr.position {
let position = position.to_logical(super::scale_factor(&common.window));
super::set_canvas_position(&common.document, &common.raw, &common.style, position);
}
if attr.fullscreen.is_some() {
common.request_fullscreen();
}
if attr.active {
let _ = common.raw.focus();
}
Ok(Canvas {
common: Common {
window,
document,
raw: canvas,
style,
old_size: Rc::default(),
current_size: Rc::default(),
wants_fullscreen: Rc::new(RefCell::new(false)),
},
common,
id,
has_focus: Arc::new(AtomicBool::new(false)),
is_intersecting: None,

View file

@ -14,7 +14,7 @@ pub use self::event_handle::EventListenerHandle;
pub use self::resize_scaling::ResizeScaleHandle;
pub use self::timeout::{IdleCallback, Timeout};
use crate::dpi::LogicalSize;
use crate::dpi::{LogicalPosition, LogicalSize};
use crate::platform::web::WindowExtWebSys;
use crate::window::Window;
use wasm_bindgen::closure::Closure;
@ -67,35 +67,107 @@ pub fn scale_factor(window: &web_sys::Window) -> f64 {
window.device_pixel_ratio()
}
pub fn set_canvas_size(
document: &Document,
raw: &HtmlCanvasElement,
style: &CssStyleDeclaration,
mut new_size: LogicalSize<f64>,
) {
if !document.contains(Some(raw)) {
return;
}
if style.get_property_value("display").unwrap() == "none" {
return;
}
fn fix_canvas_size(style: &CssStyleDeclaration, mut size: LogicalSize<f64>) -> LogicalSize<f64> {
if style.get_property_value("box-sizing").unwrap() == "border-box" {
new_size.width += style_size_property(style, "border-left-width")
size.width += style_size_property(style, "border-left-width")
+ style_size_property(style, "border-right-width")
+ style_size_property(style, "padding-left")
+ style_size_property(style, "padding-right");
new_size.height += style_size_property(style, "border-top-width")
size.height += style_size_property(style, "border-top-width")
+ style_size_property(style, "border-bottom-width")
+ style_size_property(style, "padding-top")
+ style_size_property(style, "padding-bottom");
}
size
}
pub fn set_canvas_size(
document: &Document,
raw: &HtmlCanvasElement,
style: &CssStyleDeclaration,
new_size: LogicalSize<f64>,
) {
if !document.contains(Some(raw)) || style.get_property_value("display").unwrap() == "none" {
return;
}
let new_size = fix_canvas_size(style, new_size);
set_canvas_style_property(raw, "width", &format!("{}px", new_size.width));
set_canvas_style_property(raw, "height", &format!("{}px", new_size.height));
}
pub fn set_canvas_min_size(
document: &Document,
raw: &HtmlCanvasElement,
style: &CssStyleDeclaration,
dimensions: Option<LogicalSize<f64>>,
) {
if let Some(dimensions) = dimensions {
if !document.contains(Some(raw)) || style.get_property_value("display").unwrap() == "none" {
return;
}
let new_size = fix_canvas_size(style, dimensions);
set_canvas_style_property(raw, "min-width", &format!("{}px", new_size.width));
set_canvas_style_property(raw, "min-height", &format!("{}px", new_size.height));
} else {
style
.remove_property("min-width")
.expect("Property is read only");
style
.remove_property("min-height")
.expect("Property is read only");
}
}
pub fn set_canvas_max_size(
document: &Document,
raw: &HtmlCanvasElement,
style: &CssStyleDeclaration,
dimensions: Option<LogicalSize<f64>>,
) {
if let Some(dimensions) = dimensions {
if !document.contains(Some(raw)) || style.get_property_value("display").unwrap() == "none" {
return;
}
let new_size = fix_canvas_size(style, dimensions);
set_canvas_style_property(raw, "max-width", &format!("{}px", new_size.width));
set_canvas_style_property(raw, "max-height", &format!("{}px", new_size.height));
} else {
style
.remove_property("max-width")
.expect("Property is read only");
style
.remove_property("max-height")
.expect("Property is read only");
}
}
pub fn set_canvas_position(
document: &Document,
raw: &HtmlCanvasElement,
style: &CssStyleDeclaration,
mut position: LogicalPosition<f64>,
) {
if document.contains(Some(raw)) && style.get_property_value("display").unwrap() != "none" {
position.x -= style_size_property(style, "margin-left")
+ style_size_property(style, "border-left-width")
+ style_size_property(style, "padding-left");
position.y -= style_size_property(style, "margin-top")
+ style_size_property(style, "border-top-width")
+ style_size_property(style, "padding-top");
}
set_canvas_style_property(raw, "position", "fixed");
set_canvas_style_property(raw, "left", &format!("{}px", position.x));
set_canvas_style_property(raw, "top", &format!("{}px", position.y));
}
/// This function will panic if the element is not inserted in the DOM
/// or is not a CSS property that represents a size in pixel.
pub fn style_size_property(style: &CssStyleDeclaration, property: &str) -> f64 {