paperforge_layout/
element.rs1use paperforge_core::{Color, Point, Size};
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum Align {
5 Left,
6 Center,
7 Right,
8 Justified,
9}
10
11#[derive(Debug, Clone)]
12pub enum Element {
13 Paragraph(Paragraph),
14 Heading(Heading),
15 Image(Image),
16 List(List),
17 Table(Table),
18 Spacer(Spacer),
19}
20
21#[derive(Debug, Clone)]
22pub struct Paragraph {
23 pub text: String,
24 pub align: Align,
25 pub font_size: f64,
26 pub color: Color,
27 pub line_spacing: f64,
28}
29
30impl Paragraph {
31 pub fn new(text: &str) -> Self {
32 Self {
33 text: text.to_string(),
34 align: Align::Left,
35 font_size: 12.0,
36 color: Color::black(),
37 line_spacing: 1.15,
38 }
39 }
40
41 pub fn align(mut self, align: Align) -> Self {
42 self.align = align;
43 self
44 }
45
46 pub fn font_size(mut self, size: f64) -> Self {
47 self.font_size = size;
48 self
49 }
50
51 pub fn color(mut self, color: Color) -> Self {
52 self.color = color;
53 self
54 }
55
56 pub fn line_spacing(mut self, spacing: f64) -> Self {
57 self.line_spacing = spacing;
58 self
59 }
60}
61
62#[derive(Debug, Clone)]
63pub struct Heading {
64 pub text: String,
65 pub level: u8,
66 pub font_size: f64,
67 pub color: Color,
68}
69
70impl Heading {
71 pub fn new(text: &str) -> Self {
72 Self {
73 text: text.to_string(),
74 level: 1,
75 font_size: 24.0,
76 color: Color::black(),
77 }
78 }
79
80 pub fn level(mut self, level: u8) -> Self {
81 self.level = level;
82 self
83 }
84
85 pub fn font_size(mut self, size: f64) -> Self {
86 self.font_size = size;
87 self
88 }
89
90 pub fn color(mut self, color: Color) -> Self {
91 self.color = color;
92 self
93 }
94}
95
96#[derive(Debug, Clone)]
97pub struct Image {
98 pub data: Vec<u8>,
99 pub position: Point,
100 pub size: Size,
101 pub rotation: f64,
102 pub opacity: f64,
103}
104
105impl Image {
106 pub fn new(data: Vec<u8>) -> Self {
107 Self {
108 data,
109 position: Point::new(0.0, 0.0),
110 size: Size::new(100.0, 100.0),
111 rotation: 0.0,
112 opacity: 1.0,
113 }
114 }
115
116 pub fn at(mut self, x: f64, y: f64) -> Self {
117 self.position = Point::new(x, y);
118 self
119 }
120
121 pub fn width(mut self, width: f64) -> Self {
122 self.size.width = width;
123 self
124 }
125
126 pub fn height(mut self, height: f64) -> Self {
127 self.size.height = height;
128 self
129 }
130
131 pub fn rotate(mut self, angle: f64) -> Self {
132 self.rotation = angle;
133 self
134 }
135
136 pub fn opacity(mut self, opacity: f64) -> Self {
137 self.opacity = opacity.clamp(0.0, 1.0);
138 self
139 }
140}
141
142#[derive(Debug, Clone)]
143pub enum List {
144 Unordered { items: Vec<String> },
145 Ordered { items: Vec<String> },
146}
147
148impl List {
149 pub fn unordered() -> Self {
150 Self::Unordered { items: Vec::new() }
151 }
152
153 pub fn ordered() -> Self {
154 Self::Ordered { items: Vec::new() }
155 }
156
157 pub fn item(mut self, text: &str) -> Self {
158 match &mut self {
159 Self::Unordered { items } => items.push(text.to_string()),
160 Self::Ordered { items } => items.push(text.to_string()),
161 }
162 self
163 }
164}
165
166#[derive(Debug, Clone)]
167pub struct Table {
168 pub headers: Vec<String>,
169 pub rows: Vec<Vec<String>>,
170 pub column_widths: Vec<f64>,
171}
172
173impl Table {
174 pub fn new() -> Self {
175 Self {
176 headers: Vec::new(),
177 rows: Vec::new(),
178 column_widths: Vec::new(),
179 }
180 }
181
182 pub fn header(mut self, columns: &[&str]) -> Self {
183 self.headers = columns.iter().map(|s| s.to_string()).collect();
184 self
185 }
186
187 pub fn row(mut self, cells: &[&str]) -> Self {
188 self.rows
189 .push(cells.iter().map(|s| s.to_string()).collect());
190 self
191 }
192
193 pub fn column_widths(mut self, widths: Vec<f64>) -> Self {
194 self.column_widths = widths;
195 self
196 }
197}
198
199impl Default for Table {
200 fn default() -> Self {
201 Self::new()
202 }
203}
204
205#[derive(Debug, Clone)]
206pub struct Spacer {
207 pub height: f64,
208}
209
210impl Spacer {
211 pub fn new(height: f64) -> Self {
212 Self { height }
213 }
214}