ppt_rs/generator/slide_content/
content.rs1use crate::generator::tables::Table;
4use crate::generator::shapes::Shape;
5use crate::generator::images::Image;
6use crate::generator::connectors::Connector;
7use crate::generator::media::{Video, Audio};
8use crate::generator::charts::Chart;
9
10use super::bullet::{BulletStyle, BulletPoint};
11use super::layout::SlideLayout;
12use super::code_block::CodeBlock;
13use super::transition::TransitionType;
14use super::ink_annotations::InkAnnotations;
15
16#[derive(Clone, Debug)]
18pub struct SlideContent {
19 pub title: String,
20 pub content: Vec<String>,
21 pub bullets: Vec<BulletPoint>,
23 pub bullet_style: BulletStyle,
25 pub title_size: Option<u32>,
26 pub content_size: Option<u32>,
27 pub title_bold: bool,
28 pub content_bold: bool,
29 pub title_italic: bool,
30 pub content_italic: bool,
31 pub title_underline: bool,
32 pub content_underline: bool,
33 pub title_color: Option<String>,
34 pub content_color: Option<String>,
35 pub has_table: bool,
36 pub has_chart: bool,
37 pub has_image: bool,
38 pub layout: SlideLayout,
39 pub transition: TransitionType,
40 pub table: Option<Table>,
41 pub shapes: Vec<Shape>,
42 pub images: Vec<Image>,
43 pub notes: Option<String>,
45 pub connectors: Vec<Connector>,
47 pub videos: Vec<Video>,
49 pub audios: Vec<Audio>,
51 pub charts: Vec<Chart>,
53 pub code_blocks: Vec<CodeBlock>,
55 pub ink_annotations: Option<InkAnnotations>,
57}
58
59impl SlideContent {
60 pub fn new(title: &str) -> Self {
61 SlideContent {
62 title: title.to_string(),
63 content: Vec::new(),
64 bullets: Vec::new(),
65 bullet_style: BulletStyle::Bullet,
66 title_size: Some(44),
67 content_size: Some(28),
68 title_bold: true,
69 content_bold: false,
70 title_italic: false,
71 content_italic: false,
72 title_underline: false,
73 content_underline: false,
74 title_color: None,
75 content_color: None,
76 has_table: false,
77 has_chart: false,
78 has_image: false,
79 layout: SlideLayout::TitleAndContent,
80 transition: TransitionType::None,
81 table: None,
82 shapes: Vec::new(),
83 images: Vec::new(),
84 notes: None,
85 connectors: Vec::new(),
86 videos: Vec::new(),
87 audios: Vec::new(),
88 charts: Vec::new(),
89 code_blocks: Vec::new(),
90 ink_annotations: None,
91 }
92 }
93
94 pub fn with_transition(mut self, transition: TransitionType) -> Self {
96 self.transition = transition;
97 self
98 }
99
100 pub fn add_bullet(mut self, text: &str) -> Self {
102 self.content.push(text.to_string());
103 self.bullets.push(BulletPoint::new(text).with_style(self.bullet_style));
104 self
105 }
106
107 pub fn add_styled_bullet(mut self, text: &str, style: BulletStyle) -> Self {
109 self.content.push(text.to_string());
110 self.bullets.push(BulletPoint::new(text).with_style(style));
111 self
112 }
113
114 pub fn add_numbered(mut self, text: &str) -> Self {
116 self.content.push(text.to_string());
117 self.bullets.push(BulletPoint::new(text).with_style(BulletStyle::Number));
118 self
119 }
120
121 pub fn add_lettered(mut self, text: &str) -> Self {
123 self.content.push(text.to_string());
124 self.bullets.push(BulletPoint::new(text).with_style(BulletStyle::LetterLower));
125 self
126 }
127
128 pub fn add_sub_bullet(mut self, text: &str) -> Self {
130 self.content.push(format!(" {}", text));
131 self.bullets.push(BulletPoint::new(text).with_level(1).with_style(self.bullet_style));
132 self
133 }
134
135 pub fn with_bullet_style(mut self, style: BulletStyle) -> Self {
137 self.bullet_style = style;
138 self
139 }
140
141 pub fn title_size(mut self, size: u32) -> Self {
142 self.title_size = Some(size);
143 self
144 }
145
146 pub fn content_size(mut self, size: u32) -> Self {
147 self.content_size = Some(size);
148 self
149 }
150
151 pub fn title_bold(mut self, bold: bool) -> Self {
152 self.title_bold = bold;
153 self
154 }
155
156 pub fn content_bold(mut self, bold: bool) -> Self {
157 self.content_bold = bold;
158 self
159 }
160
161 pub fn title_italic(mut self, italic: bool) -> Self {
162 self.title_italic = italic;
163 self
164 }
165
166 pub fn content_italic(mut self, italic: bool) -> Self {
167 self.content_italic = italic;
168 self
169 }
170
171 pub fn title_underline(mut self, underline: bool) -> Self {
172 self.title_underline = underline;
173 self
174 }
175
176 pub fn content_underline(mut self, underline: bool) -> Self {
177 self.content_underline = underline;
178 self
179 }
180
181 pub fn title_color(mut self, color: &str) -> Self {
182 self.title_color = Some(color.trim_start_matches('#').to_uppercase());
183 self
184 }
185
186 pub fn content_color(mut self, color: &str) -> Self {
187 self.content_color = Some(color.trim_start_matches('#').to_uppercase());
188 self
189 }
190
191 pub fn with_table(mut self) -> Self {
192 self.has_table = true;
193 self
194 }
195
196 pub fn with_chart(mut self) -> Self {
197 self.has_chart = true;
198 self
199 }
200
201 pub fn with_image(mut self) -> Self {
202 self.has_image = true;
203 self
204 }
205
206 pub fn layout(mut self, layout: SlideLayout) -> Self {
207 self.layout = layout;
208 self
209 }
210
211 pub fn table(mut self, table: Table) -> Self {
212 self.table = Some(table);
213 self.has_table = true;
214 self
215 }
216
217 pub fn add_shape(mut self, shape: Shape) -> Self {
219 self.shapes.push(shape);
220 self
221 }
222
223 pub fn with_shapes(mut self, shapes: Vec<Shape>) -> Self {
225 self.shapes.extend(shapes);
226 self
227 }
228
229 pub fn add_image(mut self, image: Image) -> Self {
231 self.images.push(image);
232 self.has_image = true;
233 self
234 }
235
236 pub fn with_images(mut self, images: Vec<Image>) -> Self {
238 self.images.extend(images);
239 self.has_image = true;
240 self
241 }
242
243 pub fn notes(mut self, notes: &str) -> Self {
245 self.notes = Some(notes.to_string());
246 self
247 }
248
249 pub fn has_notes(&self) -> bool {
251 self.notes.is_some()
252 }
253
254 pub fn add_connector(mut self, connector: Connector) -> Self {
256 self.connectors.push(connector);
257 self
258 }
259
260 pub fn with_connectors(mut self, connectors: Vec<Connector>) -> Self {
262 self.connectors.extend(connectors);
263 self
264 }
265
266 pub fn add_video(mut self, video: Video) -> Self {
268 self.videos.push(video);
269 self
270 }
271
272 pub fn with_videos(mut self, videos: Vec<Video>) -> Self {
274 self.videos.extend(videos);
275 self
276 }
277
278 pub fn add_audio(mut self, audio: Audio) -> Self {
280 self.audios.push(audio);
281 self
282 }
283
284 pub fn with_audios(mut self, audios: Vec<Audio>) -> Self {
286 self.audios.extend(audios);
287 self
288 }
289
290 pub fn add_chart(mut self, chart: Chart) -> Self {
292 self.charts.push(chart);
293 self.has_chart = true;
294 self
295 }
296
297 pub fn with_charts(mut self, charts: Vec<Chart>) -> Self {
299 self.charts.extend(charts);
300 self.has_chart = true;
301 self
302 }
303
304 pub fn with_ink(mut self, ink: InkAnnotations) -> Self {
306 self.ink_annotations = Some(ink);
307 self
308 }
309
310 pub fn has_media(&self) -> bool {
312 !self.videos.is_empty() || !self.audios.is_empty()
313 }
314
315 pub fn has_connectors(&self) -> bool {
317 !self.connectors.is_empty()
318 }
319}
320