use std::any::Any;
use anyrender::ResourceId;
use blitz_traits::events::UiEvent;
pub use style::properties::ComputedValues as ComputedStyles;
pub use anyrender::{RenderContext, Scene};
use crate::BaseDocument;
impl BaseDocument {
pub fn can_create_surfaces(&mut self, render_context: &mut dyn RenderContext) {
for &node_id in self.custom_widget_nodes.iter() {
let node = &mut self.nodes[node_id];
if let Some(widget_data) = node
.element_data_mut()
.and_then(|el| el.custom_widget_data_mut())
{
let mut render_context = ProxyRenderContext {
resource_ids: &mut widget_data.active_resource_ids,
inner: render_context,
};
widget_data
.widget
.can_create_surfaces(&mut render_context as _);
}
}
}
pub fn destroy_surfaces(&mut self) {
for &node_id in self.custom_widget_nodes.iter() {
let node = &mut self.nodes[node_id];
if let Some(widget_data) = node
.element_data_mut()
.and_then(|el| el.custom_widget_data_mut())
{
widget_data.widget.destroy_surfaces();
}
}
}
}
pub struct ProxyRenderContext<'widget, 'rend> {
pub resource_ids: &'widget mut Vec<ResourceId>,
pub inner: &'rend mut dyn RenderContext,
}
impl anyrender::RenderContext for ProxyRenderContext<'_, '_> {
fn try_register_custom_resource(
&mut self,
resource: Box<dyn Any>,
) -> Result<ResourceId, anyrender::RegisterResourceError> {
let id = self.inner.try_register_custom_resource(resource)?;
self.resource_ids.push(id);
Ok(id)
}
fn unregister_resource(&mut self, resource_id: ResourceId) {
self.resource_ids.retain(|id| *id != resource_id);
self.inner.unregister_resource(resource_id);
}
fn renderer_specific_context(&self) -> Option<Box<dyn std::any::Any>> {
self.inner.renderer_specific_context()
}
}
pub trait Widget {
fn connected(&mut self) {}
fn disconnected(&mut self) {}
fn attribute_changed(&mut self, name: &str, old_value: Option<&str>, new_value: Option<&str>) {
let _ = (name, old_value, new_value);
}
fn can_create_surfaces(&mut self, render_ctx: &mut dyn RenderContext) {
let _ = render_ctx;
}
fn destroy_surfaces(&mut self) {}
fn handle_event(&mut self, event: &UiEvent) {
let _ = event;
}
fn paint(
&mut self,
render_ctx: &mut dyn RenderContext,
styles: &ComputedStyles,
width: u32,
height: u32,
scale: f64,
) -> Scene {
let _ = (render_ctx, styles, width, height, scale);
Scene::new()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum CustomWidgetStatus {
Suspended,
Active,
PendingRemoval,
}
pub struct CustomWidgetData {
pub widget: Box<dyn Widget>,
pub status: CustomWidgetStatus,
pub active_resource_ids: Vec<ResourceId>,
}
impl CustomWidgetData {
pub(crate) fn new(widget: Box<dyn Widget>) -> Self {
Self {
widget,
status: CustomWidgetStatus::Suspended,
active_resource_ids: Vec::new(),
}
}
pub(crate) fn take_resource_ids(&mut self) -> Vec<ResourceId> {
core::mem::take(&mut self.active_resource_ids)
}
}