Skip to main content

fission_core/ui/widgets/
transform.rs

1use crate::internal::InternalLower;
2use crate::lowering::{InternalIrBuilder, InternalLoweringCx};
3use crate::ui::Widget;
4use fission_ir::{LayoutOp, Op, WidgetId};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Transform {
9    pub id: Option<WidgetId>,
10    pub transform: [f32; 16],
11    pub child: Widget,
12}
13
14impl Default for Transform {
15    fn default() -> Self {
16        Self {
17            id: None,
18            transform: [
19                1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
20            ],
21            child: crate::ui::widgets::spacer::Spacer::default().into(),
22        }
23    }
24}
25
26impl Transform {
27    pub fn new(child: impl Into<Widget>, transform: [f32; 16]) -> Self {
28        Self {
29            child: child.into(),
30            transform,
31            ..Default::default()
32        }
33    }
34}
35
36impl InternalLower for Transform {
37    fn lower(&self, cx: &mut InternalLoweringCx) -> WidgetId {
38        let id = self.id.map(Into::into).unwrap_or_else(|| cx.next_node_id());
39
40        cx.push_scope(id);
41        let child_id = self.child.lower(cx);
42        cx.pop_scope();
43
44        let mut builder = InternalIrBuilder::new(
45            id,
46            Op::Layout(LayoutOp::Transform {
47                transform: self.transform,
48            }),
49        );
50
51        builder.add_child(child_id);
52        builder.build(cx)
53    }
54}