Skip to main content

ferroui_base/rendering/composition/server/
server_composition_experimental_acrylic_visual.rs

1use super::{IServerVisualContent, ServerCompositionDrawListVisual, ServerCompositionVisual, ServerVisualRenderContext};
2use crate::platform::LtrbRect;
3use crate::rendering::composition::generated::{
4    ServerCompositionExperimentalAcrylicVisualHooks, ServerCompositionExperimentalAcrylicVisualProps,
5};
6use crate::rendering::composition::transport::BatchStreamReader;
7use crate::{Rect, RoundedRect};
8use std::any::{Any, TypeId};
9use std::time::Duration;
10
11/// Server-side counterpart of `CompositionExperimentalAcrylicVisual`: a
12/// draw list visual that draws an acrylic rectangle below its content.
13#[derive(Default)]
14pub struct ServerCompositionExperimentalAcrylicVisual {
15    draw_list: ServerCompositionDrawListVisual,
16    props: ServerCompositionExperimentalAcrylicVisualProps,
17}
18
19impl ServerCompositionExperimentalAcrylicVisual {
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    pub fn props(&self) -> &ServerCompositionExperimentalAcrylicVisualProps {
25        &self.props
26    }
27}
28
29impl ServerCompositionExperimentalAcrylicVisualHooks for ServerCompositionVisual {
30    fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration) {
31        match self.content_as::<ServerCompositionExperimentalAcrylicVisual>() {
32            Some(content) => content.draw_list.deserialize_changes_core(self, reader, committed_at),
33            None => ServerCompositionVisual::base_deserialize_changes_core(self, reader, committed_at),
34        }
35    }
36}
37
38impl IServerVisualContent for ServerCompositionExperimentalAcrylicVisual {
39    fn deserialize_changes_core(
40        &self,
41        visual: &ServerCompositionVisual,
42        reader: &mut BatchStreamReader<'_>,
43        committed_at: Duration,
44    ) {
45        self.props.deserialize_changes_core(visual, reader, committed_at);
46    }
47
48    fn render_core(
49        &self,
50        visual: &ServerCompositionVisual,
51        context: &mut ServerVisualRenderContext<'_>,
52        current_transformed_clip: LtrbRect,
53    ) {
54        let corner_radius = self.props.corner_radius();
55        let material = self.props.material();
56        let size = visual.size();
57        let rect = RoundedRect::from_corner_radius(Rect::new(0.0, 0.0, size.x, size.y), corner_radius);
58        if let Some(supported) = context.canvas().as_drawing_context_with_acrylic_like_support() {
59            supported.draw_rectangle_with_material(&material, rect);
60        }
61
62        self.draw_list.render_core(visual, context, current_transformed_clip);
63    }
64
65    fn compute_own_content_bounds(&self, visual: &ServerCompositionVisual) -> Option<LtrbRect> {
66        let size = visual.size();
67        LtrbRect::full_union(
68            self.draw_list.compute_own_content_bounds(visual),
69            Some(LtrbRect::new(0.0, 0.0, size.x, size.y)),
70        )
71    }
72
73    fn size_changed(&self, visual: &ServerCompositionVisual) {
74        visual.enqueue_for_own_bounds_recompute();
75    }
76
77    fn dependency_queued_invalidate(&self, visual: &ServerCompositionVisual) {
78        self.draw_list.dependency_queued_invalidate(visual);
79    }
80
81    fn dispose(&self, visual: &ServerCompositionVisual) {
82        self.draw_list.dispose(visual);
83    }
84
85    fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
86        self.props.find_props(type_id)
87    }
88
89    fn as_any(&self) -> &dyn Any {
90        self
91    }
92}