ferroui_base/rendering/composition/
redirect_visual.rs1use super::generated::{RedirectVisualHooks, RedirectVisualProps};
2use super::server::ServerRedirectVisual;
3use super::visual::CompositionVisualKind;
4use super::{CompositionVisual, CompositionVisualSurface, Compositor, ICompositionObject};
5use std::ops::Deref;
6use std::rc::Rc;
7
8impl RedirectVisualHooks for CompositionVisual {}
9
10#[derive(Clone)]
26pub struct RedirectVisual(Rc<CompositionVisual>);
27
28impl Deref for RedirectVisual {
29 type Target = Rc<CompositionVisual>;
30
31 fn deref(&self) -> &Rc<CompositionVisual> {
32 &self.0
33 }
34}
35
36impl RedirectVisual {
37 pub(crate) fn new(compositor: &Rc<Compositor>) -> RedirectVisual {
38 let visual = CompositionVisual::create(
39 compositor,
40 CompositionVisualKind::Redirect(RedirectVisualProps::new()),
41 || Box::new(ServerRedirectVisual::new()),
42 );
43 visual.set_clip_to_bounds(false);
45 let this = RedirectVisual(visual);
46 let surface = CompositionVisualSurface::new(compositor);
49 this.props().set_source_surface(&*this.0, Some(surface as Rc<dyn ICompositionObject>));
50 this
51 }
52
53 pub(crate) fn with_source(compositor: &Rc<Compositor>, source: Option<Rc<CompositionVisual>>) -> RedirectVisual {
54 let visual = Self::new(compositor);
55 visual.set_source(source);
56 visual
57 }
58
59 pub fn from_visual(visual: &Rc<CompositionVisual>) -> Option<RedirectVisual> {
61 matches!(visual.kind, CompositionVisualKind::Redirect(_)).then(|| RedirectVisual(visual.clone()))
62 }
63
64 pub fn visual(&self) -> &Rc<CompositionVisual> {
66 &self.0
67 }
68
69 fn props(&self) -> &RedirectVisualProps {
70 match &self.0.kind {
71 CompositionVisualKind::Redirect(props) => props,
72 _ => unreachable!("a redirect visual handle wraps a redirect visual"),
73 }
74 }
75
76 pub(crate) fn source_surface(&self) -> Option<Rc<CompositionVisualSurface>> {
78 self.props()
79 .source_surface()
80 .and_then(|surface| surface.into_any_rc().downcast::<CompositionVisualSurface>().ok())
81 }
82
83 pub fn source(&self) -> Option<Rc<CompositionVisual>> {
85 self.props().source().and_then(|visual| visual.into_any_rc().downcast::<CompositionVisual>().ok())
86 }
87
88 pub fn set_source(&self, value: Option<Rc<CompositionVisual>>) {
89 if let Some(surface) = self.source_surface() {
90 surface.set_source_visual(value.clone());
91 }
92 self.props().set_source(&*self.0, value.map(|visual| visual as Rc<dyn ICompositionObject>))
93 }
94}