hui/element/builtin/
transformer.rs1use glam::{Affine2, Vec2};
4use crate::{
5 draw::UiDrawCommand, element::{MeasureContext, ProcessContext, UiElement}, measure::Response
6};
7
8pub struct Transformer {
9 pub transform: Affine2,
10 pub element: Box<dyn UiElement>,
11}
12
13impl Transformer {
16 pub fn new(element: Box<dyn UiElement>) -> Self {
17 Self {
18 transform: Affine2::IDENTITY,
19 element,
20 }
21 }
22
23 pub fn translate(mut self, v: impl Into<Vec2>) -> Self {
24 self.transform *= Affine2::from_translation(v.into());
25 self
26 }
27
28 pub fn scale(mut self, v: impl Into<Vec2>) -> Self {
29 self.transform *= Affine2::from_scale(v.into());
30 self
31 }
32
33 pub fn rotate(mut self, radians: f32) -> Self {
34 self.transform *= Affine2::from_angle(radians);
35 self
36 }
37}
38
39impl UiElement for Transformer {
40 fn name(&self) -> &'static str {
41 "transformer"
42 }
43
44 fn measure(&self, ctx: MeasureContext) -> Response {
45 self.element.measure(ctx)
46 }
47
48 fn process(&self, ctx: ProcessContext) {
49 ctx.draw.add(UiDrawCommand::PushTransform(self.transform));
50 self.element.process(ProcessContext {
52 measure: ctx.measure,
53 state: ctx.state,
54 layout: ctx.layout,
55 draw: ctx.draw,
56 text_measure: ctx.text_measure,
57 current_font: ctx.current_font,
58 images: ctx.images,
59 input: ctx.input,
60 signal: ctx.signal,
61 });
62 ctx.draw.add(UiDrawCommand::PopTransform);
63 }
64}
65
66pub trait ElementTransformExt {
68 fn transform(self) -> Transformer;
74}
75
76impl<T: UiElement + 'static> ElementTransformExt for T {
77 fn transform(self) -> Transformer {
78 Transformer::new(Box::new(self))
79 }
80}