Skip to main content

lightweight_pdf_core/
list.rs

1//! `List` element (Phase 6, `plan/02-elementcatalog-and-features.md`):
2//! bullet/numbered items, one flat level, no nesting. Layout-wise it's
3//! sugar over `Row`/`Column` (a fixed-width marker column beside the
4//! content) — see `lightweight-pdf-layout`'s `list` module — but exists as its own
5//! element so callers don't have to hand-build that boilerplate per item.
6
7use crate::element::Element;
8use crate::style::Common;
9
10#[derive(Clone, Debug)]
11pub enum Marker {
12    Bullet,
13    /// Explicit, caller-assigned number (not auto-renumbered on removal —
14    /// `.numbered()` assigns these sequentially as items are added).
15    Number(u32),
16}
17
18#[derive(Clone, Debug)]
19pub struct ListItem {
20    pub marker: Marker,
21    pub content: Element,
22}
23
24#[derive(Clone, Debug)]
25pub struct List {
26    pub items: Vec<ListItem>,
27    pub marker_width: f32,
28    pub gap: f32,
29    next_number: u32,
30    pub common: Common,
31}
32
33impl Default for List {
34    fn default() -> Self {
35        List {
36            items: Vec::new(),
37            marker_width: 16.0,
38            gap: 6.0,
39            next_number: 1,
40            common: Common::default(),
41        }
42    }
43}
44
45impl List {
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    pub fn bullet(mut self, content: impl Into<Element>) -> Self {
51        self.items.push(ListItem {
52            marker: Marker::Bullet,
53            content: content.into(),
54        });
55        self
56    }
57
58    /// Appends a numbered item, auto-incrementing from 1.
59    pub fn numbered(mut self, content: impl Into<Element>) -> Self {
60        let n = self.next_number;
61        self.next_number += 1;
62        self.items.push(ListItem {
63            marker: Marker::Number(n),
64            content: content.into(),
65        });
66        self
67    }
68
69    pub fn marker_width(mut self, width: f32) -> Self {
70        self.marker_width = width;
71        self
72    }
73
74    pub fn gap(mut self, gap: f32) -> Self {
75        self.gap = gap;
76        self
77    }
78
79    pub fn width(mut self, width: f32) -> Self {
80        self.common.width = Some(width);
81        self
82    }
83
84    pub fn height(mut self, height: f32) -> Self {
85        self.common.height = Some(height);
86        self
87    }
88
89    pub fn flex(mut self, factor: f32) -> Self {
90        self.common.flex = Some(factor);
91        self
92    }
93
94    pub fn keep_with_next(mut self) -> Self {
95        self.common.keep_with_next = true;
96        self
97    }
98}