diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-02-17 11:55:28 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-02-17 13:28:04 +0100 |
| commit | ab95627d873239182e7b28b266f8b9f9da5cdbb1 (patch) | |
| tree | ae6589d60d32a7ae884326911600c733dc32d977 /src/library/transform.rs | |
| parent | 5965515a1ef1fe398235311185d531efc2750247 (diff) | |
Switch to const generics for nodes
Diffstat (limited to 'src/library/transform.rs')
| -rw-r--r-- | src/library/transform.rs | 81 |
1 files changed, 28 insertions, 53 deletions
diff --git a/src/library/transform.rs b/src/library/transform.rs index 6c16d02a..cc40921b 100644 --- a/src/library/transform.rs +++ b/src/library/transform.rs @@ -5,27 +5,45 @@ use crate::geom::Transform; /// Transform a node without affecting layout. #[derive(Debug, Hash)] -pub struct TransformNode<T: TransformKind> { +pub struct TransformNode<const T: TransformKind> { /// Transformation to apply to the contents. - pub kind: T, + pub transform: Transform, /// The node whose contents should be transformed. pub child: LayoutNode, } #[class] -impl<T: TransformKind> TransformNode<T> { +impl<const T: TransformKind> TransformNode<T> { /// The origin of the transformation. pub const ORIGIN: Spec<Option<Align>> = Spec::default(); fn construct(_: &mut EvalContext, args: &mut Args) -> TypResult<Template> { + let transform = match T { + MOVE => { + let tx = args.named("x")?.unwrap_or_default(); + let ty = args.named("y")?.unwrap_or_default(); + Transform::translation(tx, ty) + } + ROTATE => { + let angle = args.named_or_find("angle")?.unwrap_or_default(); + Transform::rotation(angle) + } + SCALE | _ => { + let all = args.find()?; + let sx = args.named("x")?.or(all).unwrap_or(Relative::one()); + let sy = args.named("y")?.or(all).unwrap_or(Relative::one()); + Transform::scale(sx, sy) + } + }; + Ok(Template::inline(Self { - kind: T::construct(args)?, + transform, child: args.expect("body")?, })) } } -impl<T: TransformKind> Layout for TransformNode<T> { +impl<const T: TransformKind> Layout for TransformNode<T> { fn layout( &self, ctx: &mut LayoutContext, @@ -33,14 +51,12 @@ impl<T: TransformKind> Layout for TransformNode<T> { styles: StyleChain, ) -> Vec<Constrained<Arc<Frame>>> { let origin = styles.get(Self::ORIGIN).unwrap_or(Align::CENTER_HORIZON); - let matrix = self.kind.matrix(); - let mut frames = self.child.layout(ctx, regions, styles); for Constrained { item: frame, .. } in &mut frames { let Spec { x, y } = origin.zip(frame.size).map(|(o, s)| o.resolve(s)); let transform = Transform::translation(x, y) - .pre_concat(matrix) + .pre_concat(self.transform) .pre_concat(Transform::translation(-x, -y)); Arc::make_mut(frame).transform(transform); @@ -51,54 +67,13 @@ impl<T: TransformKind> Layout for TransformNode<T> { } /// Kinds of transformations. -pub trait TransformKind: Debug + Hash + Sized + Sync + Send + 'static { - fn construct(args: &mut Args) -> TypResult<Self>; - fn matrix(&self) -> Transform; -} +pub type TransformKind = usize; /// A translation on the X and Y axes. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct Move(pub Length, pub Length); - -impl TransformKind for Move { - fn construct(args: &mut Args) -> TypResult<Self> { - let tx = args.named("x")?.unwrap_or_default(); - let ty = args.named("y")?.unwrap_or_default(); - Ok(Self(tx, ty)) - } - - fn matrix(&self) -> Transform { - Transform::translation(self.0, self.1) - } -} +pub const MOVE: TransformKind = 0; /// A rotational transformation. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct Rotate(pub Angle); - -impl TransformKind for Rotate { - fn construct(args: &mut Args) -> TypResult<Self> { - Ok(Self(args.named_or_find("angle")?.unwrap_or_default())) - } - - fn matrix(&self) -> Transform { - Transform::rotation(self.0) - } -} +pub const ROTATE: TransformKind = 1; /// A scale transformation. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct Scale(pub Relative, pub Relative); - -impl TransformKind for Scale { - fn construct(args: &mut Args) -> TypResult<Self> { - let all = args.find()?; - let sx = args.named("x")?.or(all).unwrap_or(Relative::one()); - let sy = args.named("y")?.or(all).unwrap_or(Relative::one()); - Ok(Self(sx, sy)) - } - - fn matrix(&self) -> Transform { - Transform::scale(self.0, self.1) - } -} +pub const SCALE: TransformKind = 2; |
