summaryrefslogtreecommitdiff
path: root/src/library/transform.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-02-17 11:55:28 +0100
committerLaurenz <laurmaedje@gmail.com>2022-02-17 13:28:04 +0100
commitab95627d873239182e7b28b266f8b9f9da5cdbb1 (patch)
treeae6589d60d32a7ae884326911600c733dc32d977 /src/library/transform.rs
parent5965515a1ef1fe398235311185d531efc2750247 (diff)
Switch to const generics for nodes
Diffstat (limited to 'src/library/transform.rs')
-rw-r--r--src/library/transform.rs81
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;