summaryrefslogtreecommitdiff
path: root/src/layout/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-17 17:09:19 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-17 17:09:19 +0100
commit89f2e71852e96062ea9b756bf92fbf4e894871b1 (patch)
tree836099ebd17adf30a24fc62464dfdd3d9c248480 /src/layout/mod.rs
parent9a800daa82833c57eee04e92c701ca9a05a67d3b (diff)
Align node
Diffstat (limited to 'src/layout/mod.rs')
-rw-r--r--src/layout/mod.rs47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 949fff64..33502fff 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -10,15 +10,16 @@ pub use constraints::*;
pub use incremental::*;
pub use regions::*;
+use std::any::Any;
use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use crate::font::FontStore;
use crate::frame::Frame;
-use crate::geom::{Linear, Spec};
+use crate::geom::{Align, Linear, Spec};
use crate::image::ImageStore;
-use crate::library::{DocumentNode, SizedNode};
+use crate::library::{AlignNode, DocumentNode, SizedNode};
use crate::Context;
/// Layout a document node into a collection of frames.
@@ -59,7 +60,7 @@ impl<'a> LayoutContext<'a> {
///
/// Layout return one frame per used region alongside constraints that define
/// whether the result is reusable in other regions.
-pub trait Layout: Debug {
+pub trait Layout {
/// Layout the node into the given regions, producing constrained frames.
fn layout(
&self,
@@ -70,12 +71,11 @@ pub trait Layout: Debug {
/// Convert to a packed node.
fn pack(self) -> PackedNode
where
- Self: Sized + Hash + 'static,
+ Self: Debug + Hash + Sized + 'static,
{
PackedNode {
#[cfg(feature = "layout-cache")]
hash: {
- use std::any::Any;
let mut state = fxhash::FxHasher64::default();
self.type_id().hash(&mut state);
self.hash(&mut state);
@@ -89,26 +89,40 @@ pub trait Layout: Debug {
/// A packed layouting node with precomputed hash.
#[derive(Clone)]
pub struct PackedNode {
- node: Rc<dyn Layout>,
+ node: Rc<dyn Bounds>,
#[cfg(feature = "layout-cache")]
hash: u64,
}
impl PackedNode {
+ /// Try to downcast to a specific layout node.
+ pub fn downcast<T>(&self) -> Option<&T>
+ where
+ T: Layout + Debug + Hash + 'static,
+ {
+ self.node.as_any().downcast_ref()
+ }
+
/// Force a size for this node.
- ///
- /// If at least one of `width` and `height` is `Some`, this wraps the node
- /// in a [`SizedNode`]. Otherwise, it returns the node unchanged.
pub fn sized(self, width: Option<Linear>, height: Option<Linear>) -> PackedNode {
if width.is_some() || height.is_some() {
Layout::pack(SizedNode {
- sizing: Spec::new(width, height),
child: self,
+ sizing: Spec::new(width, height),
})
} else {
self
}
}
+
+ /// Set alignments for this node.
+ pub fn aligned(self, x: Option<Align>, y: Option<Align>) -> PackedNode {
+ if x.is_some() || y.is_some() {
+ Layout::pack(AlignNode { child: self, aligns: Spec::new(x, y) })
+ } else {
+ self
+ }
+ }
}
impl Layout for PackedNode {
@@ -166,3 +180,16 @@ impl Debug for PackedNode {
self.node.fmt(f)
}
}
+
+trait Bounds: Layout + Debug + 'static {
+ fn as_any(&self) -> &dyn Any;
+}
+
+impl<T> Bounds for T
+where
+ T: Layout + Debug + 'static,
+{
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
+}