mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Support auto
as sizing for box
This commit is contained in:
parent
70c8a08905
commit
e70fbf5372
@ -41,19 +41,21 @@ use crate::prelude::*;
|
|||||||
#[capable(Layout)]
|
#[capable(Layout)]
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
pub struct BoxNode {
|
pub struct BoxNode {
|
||||||
/// How to size the content horizontally and vertically.
|
|
||||||
pub sizing: Axes<Option<Rel<Length>>>,
|
|
||||||
/// The content to be sized.
|
/// The content to be sized.
|
||||||
pub body: Content,
|
pub body: Content,
|
||||||
|
/// The box's width.
|
||||||
|
pub width: Smart<Rel<Length>>,
|
||||||
|
/// The box's height.
|
||||||
|
pub height: Smart<Rel<Length>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node]
|
#[node]
|
||||||
impl BoxNode {
|
impl BoxNode {
|
||||||
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
|
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
|
||||||
let width = args.named("width")?;
|
|
||||||
let height = args.named("height")?;
|
|
||||||
let body = args.eat::<Content>()?.unwrap_or_default();
|
let body = args.eat::<Content>()?.unwrap_or_default();
|
||||||
Ok(Self { sizing: Axes::new(width, height), body }.pack())
|
let width = args.named("width")?.unwrap_or_default();
|
||||||
|
let height = args.named("height")?.unwrap_or_default();
|
||||||
|
Ok(Self { body, width, height }.pack())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field(&self, name: &str) -> Option<Value> {
|
fn field(&self, name: &str) -> Option<Value> {
|
||||||
@ -71,31 +73,20 @@ impl Layout for BoxNode {
|
|||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
regions: Regions,
|
regions: Regions,
|
||||||
) -> SourceResult<Fragment> {
|
) -> SourceResult<Fragment> {
|
||||||
// The "pod" is the region into which the child will be layouted.
|
// Resolve the sizing to a concrete size.
|
||||||
let pod = {
|
let sizing = Axes::new(self.width, self.height);
|
||||||
// Resolve the sizing to a concrete size.
|
let size = sizing
|
||||||
let size = self
|
.resolve(styles)
|
||||||
.sizing
|
.zip(regions.base())
|
||||||
.resolve(styles)
|
.map(|(s, b)| s.map(|v| v.relative_to(b)))
|
||||||
.zip(regions.base())
|
.unwrap_or(regions.size);
|
||||||
.map(|(s, b)| s.map(|v| v.relative_to(b)))
|
|
||||||
.unwrap_or(regions.size);
|
|
||||||
|
|
||||||
// Select the appropriate base and expansion for the child depending
|
// Select the appropriate base and expansion for the child depending
|
||||||
// on whether it is automatically or relatively sized.
|
// on whether it is automatically or relatively sized.
|
||||||
let is_auto = self.sizing.as_ref().map(Option::is_none);
|
let is_auto = sizing.as_ref().map(Smart::is_auto);
|
||||||
let expand = regions.expand | !is_auto;
|
let expand = regions.expand | !is_auto;
|
||||||
Regions::one(size, expand)
|
let pod = Regions::one(size, expand);
|
||||||
};
|
self.body.layout(vt, styles, pod)
|
||||||
|
|
||||||
// Layout the child.
|
|
||||||
let mut frame = self.body.layout(vt, styles, pod)?.into_frame();
|
|
||||||
|
|
||||||
// Ensure frame size matches regions size if expansion is on.
|
|
||||||
let target = regions.expand.select(regions.size, frame.size());
|
|
||||||
frame.resize(target, Align::LEFT_TOP);
|
|
||||||
|
|
||||||
Ok(Fragment::frame(frame))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@ pub trait ContentExt {
|
|||||||
/// Link the content to a destination.
|
/// Link the content to a destination.
|
||||||
fn linked(self, dest: Destination) -> Self;
|
fn linked(self, dest: Destination) -> Self;
|
||||||
|
|
||||||
/// Force a size for this content.
|
|
||||||
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self;
|
|
||||||
|
|
||||||
/// Set alignments for this content.
|
/// Set alignments for this content.
|
||||||
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self;
|
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self;
|
||||||
|
|
||||||
@ -52,10 +49,6 @@ impl ContentExt for Content {
|
|||||||
self.styled(Meta::DATA, vec![Meta::Link(dest.clone())])
|
self.styled(Meta::DATA, vec![Meta::Link(dest.clone())])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self {
|
|
||||||
crate::layout::BoxNode { sizing, body: self }.pack()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self {
|
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self {
|
||||||
self.styled(crate::layout::AlignNode::ALIGNS, aligns)
|
self.styled(crate::layout::AlignNode::ALIGNS, aligns)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user