pub struct TableRowPart {
pub cells: Vec<TableCellPart>,
pub height: Option<i64>,
}Expand description
Table row
Fields§
§cells: Vec<TableCellPart>§height: Option<i64>Implementations§
Source§impl TableRowPart
impl TableRowPart
Sourcepub fn new(cells: Vec<TableCellPart>) -> Self
pub fn new(cells: Vec<TableCellPart>) -> Self
Create a new table row
Examples found in repository?
examples/comprehensive_demo.rs (lines 1531-1534)
68fn main() -> Result<(), Box<dyn std::error::Error>> {
69 println!("╔══════════════════════════════════════════════════════════════╗");
70 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
71 println!("╚══════════════════════════════════════════════════════════════╝\n");
72
73 let mut slides = Vec::new();
74
75 // =========================================================================
76 // SLIDE 1: CenteredTitle Layout + Title Formatting
77 // =========================================================================
78 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
79 slides.push(
80 SlideContent::new("PPTX-RS Element Showcase")
81 .layout(SlideLayout::CenteredTitle)
82 .title_size(54)
83 .title_bold(true)
84 .title_color("1F497D")
85 );
86
87 // =========================================================================
88 // SLIDE 2: TitleOnly Layout
89 // =========================================================================
90 println!("📐 Slide 2: TitleOnly Layout");
91 slides.push(
92 SlideContent::new("Section: Slide Layouts")
93 .layout(SlideLayout::TitleOnly)
94 .title_size(48)
95 .title_bold(true)
96 .title_color("C0504D")
97 );
98
99 // =========================================================================
100 // SLIDE 3: TitleAndContent Layout + All Text Formatting
101 // =========================================================================
102 println!("📝 Slide 3: TitleAndContent + Text Formatting");
103 slides.push(
104 SlideContent::new("Text Formatting Options")
105 .layout(SlideLayout::TitleAndContent)
106 .title_color("1F497D")
107 .title_bold(true)
108 .title_italic(true)
109 .title_underline(true)
110 .title_size(44)
111 .add_bullet("Normal text (default)")
112 .add_bullet("Bold content text")
113 .add_bullet("Italic content text")
114 .add_bullet("Underlined content")
115 .add_bullet("Custom font size (28pt)")
116 .add_bullet("Custom color (#4F81BD)")
117 .content_bold(true)
118 .content_italic(true)
119 .content_underline(true)
120 .content_size(28)
121 .content_color("4F81BD")
122 );
123
124 // =========================================================================
125 // SLIDE 4: TitleAndBigContent Layout
126 // =========================================================================
127 println!("📐 Slide 4: TitleAndBigContent Layout");
128 slides.push(
129 SlideContent::new("Key Highlights")
130 .layout(SlideLayout::TitleAndBigContent)
131 .title_color("1F497D")
132 .add_bullet("Large content area for emphasis")
133 .add_bullet("Perfect for key messages")
134 .add_bullet("Smaller title, bigger content")
135 .content_bold(true)
136 .content_size(32)
137 );
138
139 // =========================================================================
140 // SLIDE 5: TwoColumn Layout
141 // =========================================================================
142 println!("📐 Slide 5: TwoColumn Layout");
143 slides.push(
144 SlideContent::new("Two Column Comparison")
145 .layout(SlideLayout::TwoColumn)
146 .title_color("1F497D")
147 .add_bullet("Left Column Item 1")
148 .add_bullet("Left Column Item 2")
149 .add_bullet("Left Column Item 3")
150 .add_bullet("Right Column Item 1")
151 .add_bullet("Right Column Item 2")
152 .add_bullet("Right Column Item 3")
153 .content_size(24)
154 );
155
156 // =========================================================================
157 // SLIDE 6: Blank Layout
158 // =========================================================================
159 println!("📐 Slide 6: Blank Layout");
160 slides.push(
161 SlideContent::new("")
162 .layout(SlideLayout::Blank)
163 );
164
165 // =========================================================================
166 // SLIDE 7: Table with All Cell Styling Options
167 // =========================================================================
168 println!("📊 Slide 7: Table with Cell Styling");
169 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
170 .add_row(TableRow::new(vec![
171 TableCell::new("Header 1").bold().background_color("1F497D"),
172 TableCell::new("Header 2").bold().background_color("4F81BD"),
173 TableCell::new("Header 3").bold().background_color("8064A2"),
174 ]))
175 .add_row(TableRow::new(vec![
176 TableCell::new("Bold Cell").bold(),
177 TableCell::new("Normal Cell"),
178 TableCell::new("Colored").background_color("9BBB59"),
179 ]))
180 .add_row(TableRow::new(vec![
181 TableCell::new("Red BG").background_color("C0504D"),
182 TableCell::new("Green BG").background_color("9BBB59"),
183 TableCell::new("Blue BG").background_color("4F81BD"),
184 ]))
185 .add_row(TableRow::new(vec![
186 TableCell::new("Row 3 Col 1"),
187 TableCell::new("Row 3 Col 2"),
188 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
189 ]))
190 .position(500000, 1800000)
191 .build();
192
193 slides.push(
194 SlideContent::new("Table with Cell Styling")
195 .table(styled_table)
196 .title_color("1F497D")
197 );
198
199 // =========================================================================
200 // SLIDE 8: Charts (Bar, Line, Pie)
201 // =========================================================================
202 println!("📈 Slide 8: Chart Types");
203
204 // Create chart data structures (for demonstration)
205 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
206 .categories(vec!["North", "South", "East", "West"])
207 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
208 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
209 .build();
210
211 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
212 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
213 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
214 .build();
215
216 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
217 .categories(vec!["Product A", "Product B", "Product C", "Others"])
218 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
219 .build();
220
221 slides.push(
222 SlideContent::new("Chart Types: Bar, Line, Pie")
223 .with_chart()
224 .title_color("1F497D")
225 .add_bullet("Bar Chart: Compare categories")
226 .add_bullet("Line Chart: Show trends over time")
227 .add_bullet("Pie Chart: Show proportions")
228 .content_size(24)
229 );
230
231 // =========================================================================
232 // SLIDE 9: Shapes with Different Fills
233 // =========================================================================
234 println!("🔷 Slide 9: Shapes with Fills");
235
236 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
237 .with_fill(ShapeFill::new("4F81BD"))
238 .with_text("Rectangle");
239
240 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
241 .with_fill(ShapeFill::new("9BBB59"))
242 .with_text("Ellipse");
243
244 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
245 .with_fill(ShapeFill::new("C0504D"))
246 .with_text("Rounded");
247
248 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
249 .with_fill(ShapeFill::new("8064A2"))
250 .with_text("Triangle");
251
252 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
253 .with_fill(ShapeFill::new("F79646"))
254 .with_text("Diamond");
255
256 slides.push(
257 SlideContent::new("Shape Types with Color Fills")
258 .add_shape(rect)
259 .add_shape(ellipse)
260 .add_shape(rounded)
261 .add_shape(triangle)
262 .add_shape(diamond)
263 .title_color("1F497D")
264 );
265
266 // =========================================================================
267 // SLIDE 10: Gradient Fills (NEW)
268 // =========================================================================
269 println!("🌈 Slide 10: Gradient Fills");
270
271 // Horizontal gradient
272 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
273 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
274 .with_text("Horizontal");
275
276 // Vertical gradient
277 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
278 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
279 .with_text("Vertical");
280
281 // Diagonal gradient
282 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
283 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
284 .with_text("Diagonal");
285
286 // Three-color gradient
287 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
288 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
289 .with_text("3-Color");
290
291 // Custom angle gradient
292 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
293 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
294 .with_text("135° Angle");
295
296 slides.push(
297 SlideContent::new("Gradient Fills - Multiple Directions")
298 .add_shape(gradient_h)
299 .add_shape(gradient_v)
300 .add_shape(gradient_d)
301 .add_shape(gradient_3)
302 .add_shape(gradient_angle)
303 .title_color("1F497D")
304 );
305
306 // =========================================================================
307 // SLIDE 11: Transparency (NEW)
308 // =========================================================================
309 println!("👻 Slide 11: Transparency Effects");
310
311 // Base shape (fully opaque)
312 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
313 .with_fill(ShapeFill::new("1565C0"))
314 .with_text("Base (100%)");
315
316 // 25% transparent overlay
317 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
318 .with_fill(ShapeFill::new("F44336").with_transparency(25))
319 .with_line(ShapeLine::new("B71C1C", 25400))
320 .with_text("25% Transparent");
321
322 // 50% transparent overlay
323 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
324 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
325 .with_line(ShapeLine::new("1B5E20", 25400))
326 .with_text("50% Transparent");
327
328 // 75% transparent overlay
329 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
330 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
331 .with_line(ShapeLine::new("E65100", 25400))
332 .with_text("75% Transparent");
333
334 slides.push(
335 SlideContent::new("Transparency Effects - Overlapping Shapes")
336 .add_shape(base)
337 .add_shape(trans_25)
338 .add_shape(trans_50)
339 .add_shape(trans_75)
340 .title_color("1F497D")
341 );
342
343 // =========================================================================
344 // SLIDE 12: Styled Connectors (NEW)
345 // =========================================================================
346 println!("🔗 Slide 12: Styled Connectors");
347
348 // Create shapes to connect
349 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
350 .with_id(100)
351 .with_fill(ShapeFill::new("1565C0"))
352 .with_text("Start");
353
354 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
355 .with_id(101)
356 .with_fill(ShapeFill::new("2E7D32"))
357 .with_text("Process");
358
359 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
360 .with_id(102)
361 .with_fill(ShapeFill::new("C62828"))
362 .with_text("End");
363
364 // Straight connector with arrow
365 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
366 .with_line(ConnectorLine::new("1565C0", 25400))
367 .with_end_arrow(ArrowType::Triangle)
368 .with_arrow_size(ArrowSize::Large);
369
370 // Elbow connector with stealth arrow
371 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
372 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
373 .with_end_arrow(ArrowType::Stealth)
374 .with_arrow_size(ArrowSize::Medium);
375
376 // Curved connector examples
377 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
378 .with_id(103)
379 .with_fill(ShapeFill::new("7B1FA2"))
380 .with_text("A");
381
382 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
383 .with_id(104)
384 .with_fill(ShapeFill::new("00838F"))
385 .with_text("B");
386
387 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
388 .with_id(105)
389 .with_fill(ShapeFill::new("EF6C00"))
390 .with_text("C");
391
392 // Curved connector with diamond arrow
393 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
394 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
395 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
396
397 // Dotted connector
398 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
399 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
400 .with_end_arrow(ArrowType::Open);
401
402 slides.push(
403 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
404 .add_shape(box1)
405 .add_shape(box2)
406 .add_shape(box3)
407 .add_shape(box4)
408 .add_shape(box5)
409 .add_shape(box6)
410 .add_connector(conn1)
411 .add_connector(conn2)
412 .add_connector(conn3)
413 .add_connector(conn4)
414 .title_color("1F497D")
415 );
416
417 // =========================================================================
418 // SLIDE 13: Images
419 // =========================================================================
420 println!("🖼️ Slide 13: Image Placeholders");
421
422 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
423 .position(500000, 1600000);
424 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
425 .position(3500000, 1600000);
426 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
427 .position(6500000, 1600000);
428
429 slides.push(
430 SlideContent::new("Image Placeholders")
431 .add_image(img1)
432 .add_image(img2)
433 .add_image(img3)
434 .title_color("1F497D")
435 );
436
437 // =========================================================================
438 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
439 // =========================================================================
440 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
441
442 // Build advanced table using generator's TableBuilder with alignment
443 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
444 .add_row(TableRow::new(vec![
445 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
446 TableCell::new("").background_color("1F4E79"),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 ]))
450 .add_row(TableRow::new(vec![
451 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
452 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 ]))
456 .add_row(TableRow::new(vec![
457 TableCell::new("Product Sales").text_color("000000").align_left(),
458 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
459 TableCell::new("$450,000").text_color("C62828").align_right(),
460 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
461 ]))
462 .add_row(TableRow::new(vec![
463 TableCell::new("Services").text_color("000000").align_left(),
464 TableCell::new("$890,000").text_color("2E7D32").align_right(),
465 TableCell::new("$320,000").text_color("C62828").align_right(),
466 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
467 ]))
468 .add_row(TableRow::new(vec![
469 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
470 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
471 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
473 ]))
474 .position(300000, 1600000)
475 .build();
476
477 slides.push(
478 SlideContent::new("Financial Report - Advanced Table")
479 .table(advanced_table)
480 .title_color("1F4E79")
481 .title_bold(true)
482 );
483
484 // =========================================================================
485 // SLIDE 12: Comparison Matrix Table (NEW)
486 // =========================================================================
487 println!("📊 Slide 12: Comparison Matrix Table");
488
489 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
490 .add_row(TableRow::new(vec![
491 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
492 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
495 ]))
496 .add_row(TableRow::new(vec![
497 TableCell::new("Storage").text_color("000000"),
498 TableCell::new("5 GB").text_color("000000"),
499 TableCell::new("50 GB").text_color("000000"),
500 TableCell::new("Unlimited").bold().text_color("2E7D32"),
501 ]))
502 .add_row(TableRow::new(vec![
503 TableCell::new("Users").text_color("000000"),
504 TableCell::new("1").text_color("000000"),
505 TableCell::new("10").text_color("000000"),
506 TableCell::new("Unlimited").bold().text_color("2E7D32"),
507 ]))
508 .add_row(TableRow::new(vec![
509 TableCell::new("Support").text_color("000000"),
510 TableCell::new("Email").text_color("000000"),
511 TableCell::new("24/7 Chat").text_color("000000"),
512 TableCell::new("Dedicated").bold().text_color("2E7D32"),
513 ]))
514 .add_row(TableRow::new(vec![
515 TableCell::new("API Access").text_color("000000"),
516 TableCell::new("No").text_color("C62828"),
517 TableCell::new("Yes").text_color("2E7D32"),
518 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
519 ]))
520 .add_row(TableRow::new(vec![
521 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
522 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
525 ]))
526 .position(500000, 1600000)
527 .build();
528
529 slides.push(
530 SlideContent::new("Pricing Comparison Matrix")
531 .table(comparison_table)
532 .title_color("4472C4")
533 .title_bold(true)
534 );
535
536 // =========================================================================
537 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
538 // =========================================================================
539 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
540
541 // Create process flow using shapes
542 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
543 .with_fill(ShapeFill::new("4472C4"))
544 .with_text("1. Research");
545 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
546 .with_fill(ShapeFill::new("A5A5A5"));
547 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
548 .with_fill(ShapeFill::new("ED7D31"))
549 .with_text("2. Design");
550 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
551 .with_fill(ShapeFill::new("A5A5A5"));
552 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
553 .with_fill(ShapeFill::new("70AD47"))
554 .with_text("3. Develop");
555 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
556 .with_fill(ShapeFill::new("A5A5A5"));
557 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
558 .with_fill(ShapeFill::new("5B9BD5"))
559 .with_text("4. Deploy");
560
561 slides.push(
562 SlideContent::new("Development Process Flow")
563 .add_shape(step1)
564 .add_shape(arrow1)
565 .add_shape(step2)
566 .add_shape(arrow2)
567 .add_shape(step3)
568 .add_shape(arrow3)
569 .add_shape(step4)
570 .title_color("1F497D")
571 .title_bold(true)
572 );
573
574 // =========================================================================
575 // SLIDE 14: Organization Chart with Shapes (NEW)
576 // =========================================================================
577 println!("🔷 Slide 14: Organization Chart");
578
579 // CEO at top
580 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
581 .with_fill(ShapeFill::new("1F4E79"))
582 .with_text("CEO");
583
584 // Vertical line from CEO
585 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
586 .with_fill(ShapeFill::new("A5A5A5"));
587
588 // Horizontal connector
589 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
590 .with_fill(ShapeFill::new("A5A5A5"));
591
592 // CTO, CFO, COO
593 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
594 .with_fill(ShapeFill::new("2E75B6"))
595 .with_text("CTO");
596 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
597 .with_fill(ShapeFill::new("2E75B6"))
598 .with_text("CFO");
599 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
600 .with_fill(ShapeFill::new("2E75B6"))
601 .with_text("COO");
602
603 // Vertical lines to departments
604 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
605 .with_fill(ShapeFill::new("A5A5A5"));
606 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
607 .with_fill(ShapeFill::new("A5A5A5"));
608 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
609 .with_fill(ShapeFill::new("A5A5A5"));
610
611 // Teams under CTO
612 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
613 .with_fill(ShapeFill::new("BDD7EE"))
614 .with_text("Engineering");
615 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
616 .with_fill(ShapeFill::new("BDD7EE"))
617 .with_text("Product");
618
619 slides.push(
620 SlideContent::new("Organization Structure")
621 .add_shape(ceo)
622 .add_shape(line1)
623 .add_shape(hline)
624 .add_shape(cto)
625 .add_shape(cfo)
626 .add_shape(coo)
627 .add_shape(vline1)
628 .add_shape(vline2)
629 .add_shape(vline3)
630 .add_shape(eng)
631 .add_shape(product)
632 .title_color("1F4E79")
633 .title_bold(true)
634 );
635
636 // =========================================================================
637 // SLIDE 15: PDCA Cycle Diagram (NEW)
638 // =========================================================================
639 println!("🔷 Slide 15: PDCA Cycle Diagram");
640
641 // Four quadrants for PDCA
642 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
643 .with_fill(ShapeFill::new("4472C4"))
644 .with_text("PLAN\n\nDefine goals\nand strategy");
645 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
646 .with_fill(ShapeFill::new("ED7D31"))
647 .with_text("DO\n\nImplement\nthe plan");
648 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
649 .with_fill(ShapeFill::new("70AD47"))
650 .with_text("CHECK\n\nMeasure\nresults");
651 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
652 .with_fill(ShapeFill::new("FFC000"))
653 .with_text("ACT\n\nAdjust and\nimprove");
654
655 // Arrows between quadrants
656 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
657 .with_fill(ShapeFill::new("A5A5A5"));
658 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
659 .with_fill(ShapeFill::new("A5A5A5"));
660 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
661 .with_fill(ShapeFill::new("A5A5A5"));
662 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
663 .with_fill(ShapeFill::new("A5A5A5"));
664
665 slides.push(
666 SlideContent::new("PDCA Continuous Improvement Cycle")
667 .add_shape(plan)
668 .add_shape(do_box)
669 .add_shape(check)
670 .add_shape(act)
671 .add_shape(arr1)
672 .add_shape(arr2)
673 .add_shape(arr3)
674 .add_shape(arr4)
675 .title_color("1F497D")
676 .title_bold(true)
677 );
678
679 // =========================================================================
680 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
681 // =========================================================================
682 println!("🔷 Slide 16: Pyramid Diagram");
683
684 // Build pyramid from bottom to top
685 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
686 .with_fill(ShapeFill::new("C00000"))
687 .with_text("Physiological Needs - Food, Water, Shelter");
688 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
689 .with_fill(ShapeFill::new("ED7D31"))
690 .with_text("Safety Needs - Security, Stability");
691 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
692 .with_fill(ShapeFill::new("FFC000"))
693 .with_text("Love & Belonging - Relationships");
694 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
695 .with_fill(ShapeFill::new("70AD47"))
696 .with_text("Esteem - Achievement, Respect");
697 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
698 .with_fill(ShapeFill::new("4472C4"))
699 .with_text("Self-Actualization");
700
701 slides.push(
702 SlideContent::new("Maslow's Hierarchy of Needs")
703 .add_shape(level5)
704 .add_shape(level4)
705 .add_shape(level3)
706 .add_shape(level2)
707 .add_shape(level1)
708 .title_color("1F497D")
709 .title_bold(true)
710 );
711
712 // =========================================================================
713 // SLIDE 17: Venn Diagram (NEW)
714 // =========================================================================
715 println!("🔷 Slide 17: Venn Diagram");
716
717 // Three overlapping circles
718 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
719 .with_fill(ShapeFill::new("4472C4"))
720 .with_text("Skills");
721 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
722 .with_fill(ShapeFill::new("ED7D31"))
723 .with_text("Passion");
724 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
725 .with_fill(ShapeFill::new("70AD47"))
726 .with_text("Market Need");
727
728 // Center label
729 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
730 .with_fill(ShapeFill::new("FFFFFF"))
731 .with_text("IKIGAI");
732
733 slides.push(
734 SlideContent::new("Finding Your Ikigai - Venn Diagram")
735 .add_shape(circle1)
736 .add_shape(circle2)
737 .add_shape(circle3)
738 .add_shape(center)
739 .title_color("1F497D")
740 .title_bold(true)
741 );
742
743 // =========================================================================
744 // SLIDE 18: Timeline/Roadmap (NEW)
745 // =========================================================================
746 println!("📊 Slide 18: Project Timeline");
747
748 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
749 .add_row(TableRow::new(vec![
750 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
751 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
755 ]))
756 .add_row(TableRow::new(vec![
757 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
758 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
760 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
761 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
762 ]))
763 .add_row(TableRow::new(vec![
764 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("In Progress").text_color("ED7D31"),
767 TableCell::new("Planned").text_color("7F7F7F"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 ]))
770 .position(300000, 2000000)
771 .build();
772
773 slides.push(
774 SlideContent::new("Project Roadmap 2024-2025")
775 .table(timeline_table)
776 .title_color("1F497D")
777 .title_bold(true)
778 );
779
780 // =========================================================================
781 // SLIDE 19: Dashboard Summary (NEW)
782 // =========================================================================
783 println!("🔷 Slide 19: Dashboard with KPIs");
784
785 // KPI boxes
786 let kpi1 = Shape::new(ShapeType::RoundedRectangle, 300000, 1600000, 2000000, 1200000)
787 .with_fill(ShapeFill::new("4472C4"))
788 .with_text("Revenue\n\n$2.14M\n+15% YoY");
789 let kpi2 = Shape::new(ShapeType::RoundedRectangle, 2500000, 1600000, 2000000, 1200000)
790 .with_fill(ShapeFill::new("70AD47"))
791 .with_text("Customers\n\n12,450\n+22% YoY");
792 let kpi3 = Shape::new(ShapeType::RoundedRectangle, 4700000, 1600000, 2000000, 1200000)
793 .with_fill(ShapeFill::new("ED7D31"))
794 .with_text("NPS Score\n\n72\n+8 pts");
795 let kpi4 = Shape::new(ShapeType::RoundedRectangle, 6900000, 1600000, 2000000, 1200000)
796 .with_fill(ShapeFill::new("5B9BD5"))
797 .with_text("Retention\n\n94%\n+3% YoY");
798
799 // Status indicators
800 let status1 = Shape::new(ShapeType::Ellipse, 1800000, 2600000, 300000, 300000)
801 .with_fill(ShapeFill::new("70AD47"));
802 let status2 = Shape::new(ShapeType::Ellipse, 4000000, 2600000, 300000, 300000)
803 .with_fill(ShapeFill::new("70AD47"));
804 let status3 = Shape::new(ShapeType::Ellipse, 6200000, 2600000, 300000, 300000)
805 .with_fill(ShapeFill::new("FFC000"));
806 let status4 = Shape::new(ShapeType::Ellipse, 8400000, 2600000, 300000, 300000)
807 .with_fill(ShapeFill::new("70AD47"));
808
809 slides.push(
810 SlideContent::new("Executive Dashboard - Q1 2024")
811 .add_shape(kpi1)
812 .add_shape(kpi2)
813 .add_shape(kpi3)
814 .add_shape(kpi4)
815 .add_shape(status1)
816 .add_shape(status2)
817 .add_shape(status3)
818 .add_shape(status4)
819 .title_color("1F497D")
820 .title_bold(true)
821 );
822
823 // =========================================================================
824 // SLIDE 20: Summary Slide (NEW)
825 // =========================================================================
826 println!("📝 Slide 20: Summary with Speaker Notes");
827
828 slides.push(
829 SlideContent::new("Summary & Next Steps")
830 .layout(SlideLayout::TitleAndContent)
831 .title_color("1F497D")
832 .title_bold(true)
833 .add_bullet("Completed: Research, Design, Initial Development")
834 .add_bullet("In Progress: Sprint 3 Development")
835 .add_bullet("Next: QA Testing Phase (Q4 2024)")
836 .add_bullet("Launch Target: Q1 2025")
837 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
838 .content_size(24)
839 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
840 );
841
842 // =========================================================================
843 // SLIDE 21: Bullet Styles (NEW v0.2.1)
844 // =========================================================================
845 println!("🔢 Slide 21: Bullet Styles (NEW)");
846
847 // Numbered list
848 slides.push(
849 SlideContent::new("Bullet Styles - Numbered List")
850 .layout(SlideLayout::TitleAndContent)
851 .title_color("1F497D")
852 .title_bold(true)
853 .with_bullet_style(BulletStyle::Number)
854 .add_bullet("First numbered item")
855 .add_bullet("Second numbered item")
856 .add_bullet("Third numbered item")
857 .add_bullet("Fourth numbered item")
858 .content_size(28)
859 );
860
861 // =========================================================================
862 // SLIDE 22: Lettered Lists (NEW v0.2.1)
863 // =========================================================================
864 println!("🔤 Slide 22: Lettered Lists (NEW)");
865
866 slides.push(
867 SlideContent::new("Bullet Styles - Lettered Lists")
868 .layout(SlideLayout::TitleAndContent)
869 .title_color("1F497D")
870 .title_bold(true)
871 .add_lettered("Option A - First choice")
872 .add_lettered("Option B - Second choice")
873 .add_lettered("Option C - Third choice")
874 .add_lettered("Option D - Fourth choice")
875 .content_size(28)
876 );
877
878 // =========================================================================
879 // SLIDE 23: Roman Numerals (NEW v0.2.1)
880 // =========================================================================
881 println!("🏛️ Slide 23: Roman Numerals (NEW)");
882
883 slides.push(
884 SlideContent::new("Bullet Styles - Roman Numerals")
885 .layout(SlideLayout::TitleAndContent)
886 .title_color("1F497D")
887 .title_bold(true)
888 .with_bullet_style(BulletStyle::RomanUpper)
889 .add_bullet("Chapter I - Introduction")
890 .add_bullet("Chapter II - Background")
891 .add_bullet("Chapter III - Methodology")
892 .add_bullet("Chapter IV - Results")
893 .add_bullet("Chapter V - Conclusion")
894 .content_size(28)
895 );
896
897 // =========================================================================
898 // SLIDE 24: Custom Bullets (NEW v0.2.1)
899 // =========================================================================
900 println!("⭐ Slide 24: Custom Bullets (NEW)");
901
902 slides.push(
903 SlideContent::new("Bullet Styles - Custom Characters")
904 .layout(SlideLayout::TitleAndContent)
905 .title_color("1F497D")
906 .title_bold(true)
907 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
908 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
909 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
910 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
911 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
912 .content_size(28)
913 );
914
915 // =========================================================================
916 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
917 // =========================================================================
918 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
919
920 slides.push(
921 SlideContent::new("Bullet Styles - Hierarchical Lists")
922 .layout(SlideLayout::TitleAndContent)
923 .title_color("1F497D")
924 .title_bold(true)
925 .add_bullet("Main Topic 1")
926 .add_sub_bullet("Supporting detail A")
927 .add_sub_bullet("Supporting detail B")
928 .add_bullet("Main Topic 2")
929 .add_sub_bullet("Supporting detail C")
930 .add_sub_bullet("Supporting detail D")
931 .add_bullet("Main Topic 3")
932 .content_size(24)
933 );
934
935 // =========================================================================
936 // SLIDE 26: Text Enhancements (NEW v0.2.1)
937 // =========================================================================
938 println!("✏️ Slide 26: Text Enhancements (NEW)");
939
940 // Use BulletPoint with formatting
941 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
942 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
943 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
944 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
945 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
946
947 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
948 .layout(SlideLayout::TitleAndContent)
949 .title_color("1F497D")
950 .title_bold(true)
951 .content_size(24);
952 text_enhancements_slide.bullets.push(strikethrough_bullet);
953 text_enhancements_slide.bullets.push(highlight_bullet);
954 text_enhancements_slide.bullets.push(subscript_bullet);
955 text_enhancements_slide.bullets.push(superscript_bullet);
956 text_enhancements_slide.bullets.push(bold_colored);
957
958 slides.push(text_enhancements_slide);
959
960 // =========================================================================
961 // SLIDE 27: Font Size Presets (NEW v0.2.1)
962 // =========================================================================
963 println!("🔤 Slide 27: Font Size Presets (NEW)");
964
965 // Demonstrate different font sizes per bullet
966 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
967 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
968 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
969 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
970 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
971
972 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
973 .layout(SlideLayout::TitleAndContent)
974 .title_color("1F497D")
975 .title_bold(true)
976 .title_size(font_sizes::TITLE);
977 font_size_slide.bullets.push(large_bullet);
978 font_size_slide.bullets.push(heading_bullet);
979 font_size_slide.bullets.push(body_bullet);
980 font_size_slide.bullets.push(small_bullet);
981 font_size_slide.bullets.push(caption_bullet);
982
983 slides.push(font_size_slide);
984
985 // =========================================================================
986 // SLIDE 28: Theme Colors (NEW v0.2.1)
987 // =========================================================================
988 println!("🎨 Slide 28: Theme Colors (NEW)");
989
990 // Create shapes with theme colors
991 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
992 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
993 .with_text("Corporate");
994
995 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
996 .with_fill(ShapeFill::new(themes::MODERN.primary))
997 .with_text("Modern");
998
999 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1000 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1001 .with_text("Vibrant");
1002
1003 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1004 .with_fill(ShapeFill::new(themes::DARK.primary))
1005 .with_text("Dark");
1006
1007 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::NATURE.primary))
1009 .with_text("Nature");
1010
1011 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::TECH.primary))
1013 .with_text("Tech");
1014
1015 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::CARBON.primary))
1017 .with_text("Carbon");
1018
1019 slides.push(
1020 SlideContent::new("Theme Color Palettes")
1021 .layout(SlideLayout::TitleAndContent)
1022 .title_color("1F497D")
1023 .title_bold(true)
1024 .add_shape(corporate_shape)
1025 .add_shape(modern_shape)
1026 .add_shape(vibrant_shape)
1027 .add_shape(dark_shape)
1028 .add_shape(nature_shape)
1029 .add_shape(tech_shape)
1030 .add_shape(carbon_shape)
1031 );
1032
1033 // =========================================================================
1034 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1035 // =========================================================================
1036 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1037
1038 // Material Design colors
1039 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1040 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1041 .with_text("M-Red");
1042
1043 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1044 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1045 .with_text("M-Blue");
1046
1047 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1048 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1049 .with_text("M-Green");
1050
1051 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1052 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1053 .with_text("M-Orange");
1054
1055 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1057 .with_text("M-Purple");
1058
1059 // Carbon Design colors
1060 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1061 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1062 .with_text("C-Blue");
1063
1064 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1065 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1066 .with_text("C-Green");
1067
1068 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1069 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1070 .with_text("C-Red");
1071
1072 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1073 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1074 .with_text("C-Purple");
1075
1076 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1078 .with_text("C-Gray");
1079
1080 slides.push(
1081 SlideContent::new("Material & Carbon Design Colors")
1082 .layout(SlideLayout::TitleAndContent)
1083 .title_color("1F497D")
1084 .title_bold(true)
1085 .add_shape(material_red)
1086 .add_shape(material_blue)
1087 .add_shape(material_green)
1088 .add_shape(material_orange)
1089 .add_shape(material_purple)
1090 .add_shape(carbon_blue)
1091 .add_shape(carbon_green)
1092 .add_shape(carbon_red)
1093 .add_shape(carbon_purple)
1094 .add_shape(carbon_gray)
1095 );
1096
1097 // =========================================================================
1098 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1099 // =========================================================================
1100 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1101
1102 // 1x1 red PNG pixel in base64
1103 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1104
1105 // Create image from base64 (demonstrating the API)
1106 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1107 .position(4000000, 2500000)
1108 .build();
1109
1110 slides.push(
1111 SlideContent::new("Image Loading - New Methods")
1112 .layout(SlideLayout::TitleAndContent)
1113 .title_color("1F497D")
1114 .title_bold(true)
1115 .add_bullet("Image::new(path) - Load from file path")
1116 .add_bullet("Image::from_base64(data) - Load from base64 string")
1117 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1118 .add_bullet("ImageBuilder for fluent API configuration")
1119 .add_bullet("Built-in base64 decoder (no external deps)")
1120 .content_size(24)
1121 );
1122
1123 // =========================================================================
1124 // SLIDE 31: Feature Summary (NEW v0.2.1)
1125 // =========================================================================
1126 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1127
1128 slides.push(
1129 SlideContent::new("New Features in v0.2.1")
1130 .layout(SlideLayout::TitleAndContent)
1131 .title_color("1F497D")
1132 .title_bold(true)
1133 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1134 .add_numbered("TextFormat: Strikethrough, Highlight")
1135 .add_numbered("TextFormat: Subscript, Superscript")
1136 .add_numbered("Font size presets in prelude")
1137 .add_numbered("Image::from_base64 and from_bytes")
1138 .add_numbered("Theme color palettes (7 themes)")
1139 .add_numbered("Material & Carbon Design colors")
1140 .content_size(24)
1141 );
1142
1143 // =========================================================================
1144 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1145 // =========================================================================
1146 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1147
1148 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1149 let show_kiosk = SlideShowSettings::kiosk();
1150 let _show_range = SlideShowSettings::new()
1151 .show_type(ShowType::Browsed)
1152 .slide_range(SlideRange::Range { start: 1, end: 10 })
1153 .without_animation(true);
1154 let _speaker_xml = show_speaker.to_xml();
1155 let _kiosk_xml = show_kiosk.to_xml();
1156
1157 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1158 .add_row(TableRow::new(vec![
1159 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1160 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1161 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1162 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1163 ]))
1164 .add_row(TableRow::new(vec![
1165 TableCell::new("Loop").bold().background_color("D6E4F0"),
1166 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1167 TableCell::new("No"),
1168 ]))
1169 .add_row(TableRow::new(vec![
1170 TableCell::new("Narration").bold().background_color("D6E4F0"),
1171 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1172 TableCell::new("Yes"),
1173 ]))
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Animation").bold().background_color("D6E4F0"),
1176 TableCell::new("Yes"), TableCell::new("Yes"),
1177 TableCell::new("No").text_color("C62828"),
1178 ]))
1179 .add_row(TableRow::new(vec![
1180 TableCell::new("Timings").bold().background_color("D6E4F0"),
1181 TableCell::new("Yes"), TableCell::new("Auto"),
1182 TableCell::new("Yes"),
1183 ]))
1184 .add_row(TableRow::new(vec![
1185 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1186 TableCell::new("All"), TableCell::new("All"),
1187 TableCell::new("1-10"),
1188 ]))
1189 .add_row(TableRow::new(vec![
1190 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1191 TableCell::new("Red").text_color("FF0000"),
1192 TableCell::new("Red").text_color("FF0000"),
1193 TableCell::new("Red").text_color("FF0000"),
1194 ]))
1195 .position(300000, 1600000)
1196 .build();
1197
1198 // Mode icons
1199 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1200 .with_fill(ShapeFill::new("4472C4"))
1201 .with_text("Speaker: Full control");
1202 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1203 .with_fill(ShapeFill::new("ED7D31"))
1204 .with_text("Kiosk: Auto-loop");
1205 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1206 .with_fill(ShapeFill::new("70AD47"))
1207 .with_text("Browsed: Scrollbar");
1208
1209 slides.push(
1210 SlideContent::new("Slide Show Settings - Mode Comparison")
1211 .table(show_table)
1212 .add_shape(icon_speaker)
1213 .add_shape(icon_kiosk)
1214 .add_shape(icon_browsed)
1215 .title_color("1F497D")
1216 .title_bold(true)
1217 );
1218
1219 // =========================================================================
1220 // SLIDE 35: Print Settings - Visual Handout Grid
1221 // =========================================================================
1222 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1223
1224 let print = PrintSettings::new()
1225 .print_what(PrintWhat::Handouts)
1226 .color_mode(PrintColorMode::Grayscale)
1227 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1228 .frame_slides(true)
1229 .header("Q1 2025 Strategy Review")
1230 .footer("Confidential - Internal Use Only")
1231 .print_date(true)
1232 .print_page_numbers(true);
1233 let _prnpr_xml = print.to_prnpr_xml();
1234 let _handout_xml = print.to_handout_master_xml();
1235
1236 // Visual: 6-slide handout grid (2 cols x 3 rows)
1237 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1238 .with_fill(ShapeFill::new("E7E6E6"))
1239 .with_text("Q1 2025 Strategy Review");
1240 // Row 1
1241 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1242 .with_line(ShapeLine::new("999999", 12700))
1243 .with_text("Slide 1");
1244 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1245 .with_line(ShapeLine::new("999999", 12700))
1246 .with_text("Slide 2");
1247 // Row 2
1248 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1249 .with_line(ShapeLine::new("999999", 12700))
1250 .with_text("Slide 3");
1251 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1252 .with_line(ShapeLine::new("999999", 12700))
1253 .with_text("Slide 4");
1254 // Row 3
1255 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1256 .with_line(ShapeLine::new("999999", 12700))
1257 .with_text("Slide 5");
1258 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1259 .with_line(ShapeLine::new("999999", 12700))
1260 .with_text("Slide 6");
1261 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1262 .with_fill(ShapeFill::new("E7E6E6"))
1263 .with_text("Confidential - Internal Use Only");
1264
1265 // Settings summary table on the right
1266 let print_table = TableBuilder::new(vec![1800000, 2000000])
1267 .add_row(TableRow::new(vec![
1268 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1269 TableCell::new("").background_color("1F4E79"),
1270 ]))
1271 .add_row(TableRow::new(vec![
1272 TableCell::new("Print What").bold().background_color("D6E4F0"),
1273 TableCell::new("Handouts"),
1274 ]))
1275 .add_row(TableRow::new(vec![
1276 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1277 TableCell::new("Grayscale"),
1278 ]))
1279 .add_row(TableRow::new(vec![
1280 TableCell::new("Layout").bold().background_color("D6E4F0"),
1281 TableCell::new("6 slides/page"),
1282 ]))
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1285 TableCell::new("Yes"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Date").bold().background_color("D6E4F0"),
1289 TableCell::new("Yes"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1293 TableCell::new("Yes"),
1294 ]))
1295 .position(5000000, 1800000)
1296 .build();
1297
1298 slides.push(
1299 SlideContent::new("Print Handout - 6 Slides Per Page")
1300 .table(print_table)
1301 .add_shape(hdr)
1302 .add_shape(s1).add_shape(s2)
1303 .add_shape(s3).add_shape(s4)
1304 .add_shape(s5).add_shape(s6)
1305 .add_shape(ftr)
1306 .title_color("1F497D")
1307 .title_bold(true)
1308 );
1309
1310 // =========================================================================
1311 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1312 // =========================================================================
1313 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1314
1315 // Use TableMergeMap to compute states, then build a visual table
1316 let mut merge_map = TableMergeMap::new(5, 4);
1317 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1318 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1319 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1320
1321 // Show merge state labels
1322 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1323 let state_01 = merge_map.cell_state(0, 1); // HMerge
1324 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1325 let state_20 = merge_map.cell_state(2, 0); // VMerge
1326 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1327 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1328 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1329 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1330
1331 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1332 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1333 .add_row(TableRow::new(vec![
1334 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1335 TableCell::new("").background_color("1F4E79").h_merge(),
1336 TableCell::new("").background_color("1F4E79").h_merge(),
1337 TableCell::new("").background_color("1F4E79").h_merge(),
1338 ]))
1339 .add_row(TableRow::new(vec![
1340 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1341 TableCell::new("Hardware").background_color("E2EFDA"),
1342 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1343 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1344 ]))
1345 .add_row(TableRow::new(vec![
1346 TableCell::new("").background_color("BDD7EE").v_merge(),
1347 TableCell::new("Software").background_color("E2EFDA"),
1348 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1349 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1350 ]))
1351 .add_row(TableRow::new(vec![
1352 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1353 TableCell::new("Consulting").background_color("FFF2CC"),
1354 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1355 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1356 ]))
1357 .add_row(TableRow::new(vec![
1358 TableCell::new("").background_color("FCE4D6").v_merge(),
1359 TableCell::new("Support").background_color("FFF2CC"),
1360 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1361 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1362 ]))
1363 .position(300000, 1600000)
1364 .build();
1365
1366 // Legend shapes
1367 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1368 .with_fill(ShapeFill::new("4472C4"))
1369 .with_text("Anchor (gridSpan/rowSpan)");
1370 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1371 .with_fill(ShapeFill::new("ED7D31"))
1372 .with_text("hMerge (col covered)");
1373 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1374 .with_fill(ShapeFill::new("70AD47"))
1375 .with_text("vMerge (row covered)");
1376 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1377 .with_fill(ShapeFill::new("A5A5A5"))
1378 .with_text("Normal (no merge)");
1379
1380 slides.push(
1381 SlideContent::new("Advanced Table Merging - Merged Cells")
1382 .table(merge_table)
1383 .add_shape(legend_anchor)
1384 .add_shape(legend_hmerge)
1385 .add_shape(legend_vmerge)
1386 .add_shape(legend_normal)
1387 .title_color("1F497D")
1388 .title_bold(true)
1389 );
1390
1391 // =========================================================================
1392 // Build PresentationSettings with all advanced features
1393 // =========================================================================
1394 println!("\n⚙️ Building Presentation Settings...");
1395
1396 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1397 let show_settings = SlideShowSettings::new()
1398 .show_type(ShowType::Speaker)
1399 .pen_color(PenColor::red())
1400 .use_timings(true);
1401 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1402 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1403
1404 // Print settings (embedded in presProps.xml as <p:prnPr>)
1405 let print_settings = PrintSettings::new()
1406 .print_what(PrintWhat::Handouts)
1407 .color_mode(PrintColorMode::Grayscale)
1408 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1409 .frame_slides(true)
1410 .header("Q1 2025 Strategy Review")
1411 .footer("Confidential - Internal Use Only")
1412 .print_date(true)
1413 .print_page_numbers(true);
1414 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1415 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1416
1417 let pres_settings = PresentationSettings::new()
1418 .slide_show(show_settings)
1419 .print(print_settings);
1420 println!(" All settings configured → presProps.xml");
1421
1422 // =========================================================================
1423 // Generate PPTX with real integrated features
1424 // =========================================================================
1425 println!("\n📦 Generating PPTX with integrated features...");
1426 let pptx_data = create_pptx_with_settings(
1427 "PPTX-RS Element Showcase",
1428 slides.clone(),
1429 Some(pres_settings),
1430 )?;
1431 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1432 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1433 slides.len(), pptx_data.len());
1434
1435 // =========================================================================
1436 // Package Analysis - Demonstrate Reading
1437 // =========================================================================
1438 println!("\n📖 Package Analysis (Read Capability):");
1439
1440 let package = Package::open("comprehensive_demo.pptx")?;
1441 let paths = package.part_paths();
1442
1443 let slide_count = paths.iter()
1444 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1445 .count();
1446
1447 println!(" ├── Total parts: {}", package.part_count());
1448 println!(" ├── Slides: {}", slide_count);
1449 println!(" └── Package opened and analyzed successfully");
1450
1451 // =========================================================================
1452 // NEW: Parts API Demonstration
1453 // =========================================================================
1454 println!("\n🧩 Parts API Demonstration:");
1455
1456 // SlideLayoutPart - 11 layout types
1457 println!(" ┌── SlideLayoutPart (11 layout types):");
1458 let layouts = [
1459 LayoutType::Title,
1460 LayoutType::TitleAndContent,
1461 LayoutType::SectionHeader,
1462 LayoutType::TwoContent,
1463 LayoutType::Comparison,
1464 LayoutType::TitleOnly,
1465 LayoutType::Blank,
1466 LayoutType::ContentWithCaption,
1467 LayoutType::PictureWithCaption,
1468 LayoutType::TitleAndVerticalText,
1469 LayoutType::VerticalTitleAndText,
1470 ];
1471 for (i, layout_type) in layouts.iter().enumerate() {
1472 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1473 if i < 3 {
1474 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1475 }
1476 }
1477 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1478
1479 // SlideMasterPart
1480 println!(" ├── SlideMasterPart:");
1481 let mut master = SlideMasterPart::new(1);
1482 master.set_name("Custom Master");
1483 master.add_layout_rel_id("rId2");
1484 master.add_layout_rel_id("rId3");
1485 println!(" │ ├── Name: {}", master.name());
1486 println!(" │ ├── Path: {}", master.path());
1487 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1488
1489 // ThemePart - Colors and Fonts
1490 println!(" ├── ThemePart (colors & fonts):");
1491 let mut theme = ThemePart::new(1);
1492 theme.set_name("Corporate Theme");
1493 theme.set_major_font("Arial");
1494 theme.set_minor_font("Calibri");
1495 theme.set_color("accent1", "FF5733");
1496 theme.set_color("accent2", "33FF57");
1497 let theme_xml = theme.to_xml()?;
1498 println!(" │ ├── Name: {}", theme.name());
1499 println!(" │ ├── Major Font: Arial");
1500 println!(" │ ├── Minor Font: Calibri");
1501 println!(" │ └── XML size: {} bytes", theme_xml.len());
1502
1503 // NotesSlidePart - Speaker notes
1504 println!(" ├── NotesSlidePart (speaker notes):");
1505 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1506 let notes_xml = notes.to_xml()?;
1507 println!(" │ ├── Path: {}", notes.path());
1508 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1509 println!(" │ └── XML size: {} bytes", notes_xml.len());
1510
1511 // AppPropertiesPart - Application metadata
1512 println!(" ├── AppPropertiesPart (metadata):");
1513 let mut app_props = AppPropertiesPart::new();
1514 app_props.set_company("Acme Corporation");
1515 app_props.set_slides(slides.len() as u32);
1516 let app_xml = app_props.to_xml()?;
1517 println!(" │ ├── Company: Acme Corporation");
1518 println!(" │ ├── Slides: {}", slides.len());
1519 println!(" │ └── XML size: {} bytes", app_xml.len());
1520
1521 // MediaPart - Video/Audio formats
1522 println!(" ├── MediaPart (10 media formats):");
1523 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1524 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1525 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1526 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1527
1528 // TablePart - Table with formatting
1529 println!(" ├── TablePart (cell formatting):");
1530 let table_part = TablePart::new()
1531 .add_row(TableRowPart::new(vec![
1532 TableCellPart::new("Header 1").bold().background("4472C4"),
1533 TableCellPart::new("Header 2").bold().background("4472C4"),
1534 ]))
1535 .add_row(TableRowPart::new(vec![
1536 TableCellPart::new("Data 1").color("333333"),
1537 TableCellPart::new("Data 2").italic(),
1538 ]))
1539 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1540 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1541 let table_xml = table_part.to_slide_xml(10);
1542 println!(" │ ├── Rows: {}", table_part.rows.len());
1543 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1544 println!(" │ └── XML size: {} bytes", table_xml.len());
1545
1546 // ContentTypesPart
1547 println!(" └── ContentTypesPart:");
1548 let mut content_types = ContentTypesPart::new();
1549 content_types.add_presentation();
1550 content_types.add_slide(1);
1551 content_types.add_slide_layout(1);
1552 content_types.add_slide_master(1);
1553 content_types.add_theme(1);
1554 content_types.add_core_properties();
1555 content_types.add_app_properties();
1556 let ct_xml = content_types.to_xml()?;
1557 println!(" ├── Path: {}", content_types.path());
1558 println!(" └── XML size: {} bytes", ct_xml.len());
1559
1560 // =========================================================================
1561 // NEW: Elements API Demonstration
1562 // =========================================================================
1563 println!("\n🎨 Elements API Demonstration:");
1564
1565 // Color types
1566 println!(" ┌── Color Types:");
1567 let rgb = RgbColor::new(255, 87, 51);
1568 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1569 let scheme = SchemeColor::Accent1;
1570 let color = Color::rgb(100, 149, 237);
1571 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1572 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1573 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1574 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1575
1576 // Position and Size
1577 println!(" ├── Position & Size (EMU units):");
1578 let pos = Position::from_inches(1.0, 2.0);
1579 let size = Size::from_inches(4.0, 3.0);
1580 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1581 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1582 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1583
1584 // Transform
1585 println!(" └── Transform (position + size + rotation):");
1586 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1587 let transform_xml = transform.to_xml();
1588 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1589 println!(" ├── .with_rotation(45.0)");
1590 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1591
1592 // =========================================================================
1593 // NEW: Advanced Features Demonstration
1594 // =========================================================================
1595 println!("\n🚀 Advanced Features Demonstration:");
1596
1597 // -------------------------------------------------------------------------
1598 // Complex Table Examples
1599 // -------------------------------------------------------------------------
1600 println!(" ┌── Complex Table Examples:");
1601
1602 // Example 1: Financial Report Table
1603 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1604 let financial_table = TablePart::new()
1605 .add_row(TableRowPart::new(vec![
1606 TableCellPart::new("Q1 2024 Financial Summary")
1607 .col_span(4)
1608 .bold()
1609 .center()
1610 .background("1F4E79")
1611 .color("FFFFFF")
1612 .font_size(14)
1613 .font("Arial Black"),
1614 ]))
1615 .add_row(TableRowPart::new(vec![
1616 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1617 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1618 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1619 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1620 ]))
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1623 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1624 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1625 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1626 ]))
1627 .add_row(TableRowPart::new(vec![
1628 TableCellPart::new("Services").align(HorizontalAlign::Left),
1629 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1630 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1631 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1632 ]))
1633 .add_row(TableRowPart::new(vec![
1634 TableCellPart::new("Total").bold().background("E7E6E6"),
1635 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1636 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1637 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1638 ]))
1639 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1640 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1641 let fin_xml = financial_table.to_slide_xml(100);
1642 println!(" │ │ ├── Merged header spanning 4 columns");
1643 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1644 println!(" │ │ ├── Custom fonts and sizes");
1645 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1646
1647 // Example 2: Comparison Matrix
1648 println!(" │ ├── Comparison Matrix (features vs products):");
1649 let matrix_table = TablePart::new()
1650 .add_row(TableRowPart::new(vec![
1651 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1652 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1653 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1654 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1655 ]))
1656 .add_row(TableRowPart::new(vec![
1657 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1658 TableCellPart::new("5 GB").center(),
1659 TableCellPart::new("50 GB").center(),
1660 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1661 ]))
1662 .add_row(TableRowPart::new(vec![
1663 TableCellPart::new("Users").align(HorizontalAlign::Left),
1664 TableCellPart::new("1").center(),
1665 TableCellPart::new("10").center(),
1666 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1667 ]))
1668 .add_row(TableRowPart::new(vec![
1669 TableCellPart::new("Support").align(HorizontalAlign::Left),
1670 TableCellPart::new("Email").center(),
1671 TableCellPart::new("24/7 Chat").center(),
1672 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1673 ]))
1674 .add_row(TableRowPart::new(vec![
1675 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1676 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1677 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1678 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1679 ]));
1680 println!(" │ │ └── 5x4 matrix with alternating styles");
1681
1682 // Example 3: Schedule/Timeline Table
1683 println!(" │ └── Schedule Table (with row spans):");
1684 let schedule_table = TablePart::new()
1685 .add_row(TableRowPart::new(vec![
1686 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1687 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1688 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1692 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1693 TableCellPart::new("Code Review").center(),
1694 ]))
1695 .add_row(TableRowPart::new(vec![
1696 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1697 TableCellPart::merged(),
1698 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1699 ]));
1700 println!(" │ └── Row spans for multi-hour events");
1701
1702 // -------------------------------------------------------------------------
1703 // Complex Animation Sequences
1704 // -------------------------------------------------------------------------
1705 println!(" ├── Complex Animation Sequences:");
1706
1707 // Sequence 1: Title entrance with staggered content
1708 println!(" │ ┌── Staggered Entrance Sequence:");
1709 let title_anim = Animation::new(2, AnimationEffect::Fade)
1710 .trigger(AnimationTrigger::OnClick)
1711 .duration(500);
1712 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1713 .trigger(AnimationTrigger::AfterPrevious)
1714 .direction(AnimationDirection::Left)
1715 .duration(400)
1716 .delay(200);
1717 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1718 .trigger(AnimationTrigger::AfterPrevious)
1719 .direction(AnimationDirection::Left)
1720 .duration(400)
1721 .delay(100);
1722 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1723 .trigger(AnimationTrigger::AfterPrevious)
1724 .direction(AnimationDirection::Left)
1725 .duration(400)
1726 .delay(100);
1727 let staggered = SlideAnimations::new()
1728 .add(title_anim)
1729 .add(content1)
1730 .add(content2)
1731 .add(content3)
1732 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1733 let staggered_xml = staggered.to_timing_xml()?;
1734 println!(" │ │ ├── Title: Fade on click");
1735 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1736 println!(" │ │ ├── Transition: Push from left (750ms)");
1737 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1738
1739 // Sequence 2: Emphasis and exit
1740 println!(" │ ├── Emphasis + Exit Sequence:");
1741 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1742 .trigger(AnimationTrigger::OnClick)
1743 .duration(1000)
1744 .repeat(3);
1745 let exit = Animation::new(6, AnimationEffect::FadeOut)
1746 .trigger(AnimationTrigger::AfterPrevious)
1747 .duration(500);
1748 let emphasis_seq = SlideAnimations::new()
1749 .add(emphasis)
1750 .add(exit);
1751 println!(" │ │ ├── Pulse 3x on click, then fade out");
1752 println!(" │ │ └── Same shape, sequential effects");
1753
1754 // Sequence 3: Motion path
1755 println!(" │ └── Motion Path Animation:");
1756 let motion = Animation::new(7, AnimationEffect::Lines)
1757 .trigger(AnimationTrigger::OnClick)
1758 .duration(2000);
1759 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1760
1761 // -------------------------------------------------------------------------
1762 // SmartArt Combinations
1763 // -------------------------------------------------------------------------
1764 println!(" ├── SmartArt Layout Examples:");
1765
1766 // Process flow
1767 println!(" │ ┌── Process Flow (5 steps):");
1768 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1769 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1770 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1771 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1772 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1773
1774 // Organization chart
1775 println!(" │ ├── Organization Chart:");
1776 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1777 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1778 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1779
1780 // Cycle diagram
1781 println!(" │ ├── Cycle Diagram:");
1782 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1783 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1784 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1785
1786 // Venn diagram
1787 println!(" │ ├── Venn Diagram:");
1788 let venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1789 .add_items(vec!["Skills", "Passion", "Market Need"]);
1790 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1791
1792 // Pyramid
1793 println!(" │ └── Pyramid:");
1794 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1795 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1796 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1797
1798 // -------------------------------------------------------------------------
1799 // 3D Model Configurations
1800 // -------------------------------------------------------------------------
1801 println!(" ├── 3D Model Configurations:");
1802
1803 // Product showcase
1804 println!(" │ ┌── Product Showcase:");
1805 let product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1806 .camera(CameraPreset::IsometricTopUp)
1807 .rotation(0.0, 45.0, 0.0)
1808 .zoom(1.2)
1809 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1810 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1811 println!(" │ │ ├── Camera: Isometric top-up view");
1812 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1813 println!(" │ │ └── Zoom: 1.2x for detail");
1814
1815 // Architectural model
1816 println!(" │ ├── Architectural Model:");
1817 let arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1818 .camera(CameraPreset::Front)
1819 .rotation(15.0, -30.0, 0.0)
1820 .ambient_light("FFFFCC");
1821 println!(" │ │ ├── Camera: Front view with tilt");
1822 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1823
1824 // Technical diagram
1825 println!(" │ └── Technical Diagram:");
1826 let tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1827 .camera(CameraPreset::IsometricOffAxis1Top)
1828 .rotation(0.0, 0.0, 0.0);
1829 println!(" │ └── Camera: Off-axis isometric for exploded view");
1830
1831 // -------------------------------------------------------------------------
1832 // Theme + Master + Layout Combination
1833 // -------------------------------------------------------------------------
1834 println!(" ├── Theme + Master + Layout Integration:");
1835
1836 // Corporate theme
1837 let mut corp_theme = ThemePart::new(1);
1838 corp_theme.set_name("Corporate Blue");
1839 corp_theme.set_major_font("Segoe UI");
1840 corp_theme.set_minor_font("Segoe UI Light");
1841 corp_theme.set_color("dk1", "000000");
1842 corp_theme.set_color("lt1", "FFFFFF");
1843 corp_theme.set_color("dk2", "1F497D");
1844 corp_theme.set_color("lt2", "EEECE1");
1845 corp_theme.set_color("accent1", "4472C4");
1846 corp_theme.set_color("accent2", "ED7D31");
1847 corp_theme.set_color("accent3", "A5A5A5");
1848 corp_theme.set_color("accent4", "FFC000");
1849 corp_theme.set_color("accent5", "5B9BD5");
1850 corp_theme.set_color("accent6", "70AD47");
1851 let theme_xml = corp_theme.to_xml()?;
1852 println!(" │ ├── Theme: Corporate Blue");
1853 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1854 println!(" │ │ ├── 12 color slots defined");
1855 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1856
1857 // Master with multiple layouts
1858 let mut corp_master = SlideMasterPart::new(1);
1859 corp_master.set_name("Corporate Master");
1860 corp_master.add_layout_rel_id("rId2"); // Title
1861 corp_master.add_layout_rel_id("rId3"); // Title + Content
1862 corp_master.add_layout_rel_id("rId4"); // Section Header
1863 corp_master.add_layout_rel_id("rId5"); // Two Content
1864 corp_master.add_layout_rel_id("rId6"); // Comparison
1865 corp_master.add_layout_rel_id("rId7"); // Title Only
1866 corp_master.add_layout_rel_id("rId8"); // Blank
1867 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1868
1869 // -------------------------------------------------------------------------
1870 // VBA + Custom XML Integration
1871 // -------------------------------------------------------------------------
1872 println!(" ├── VBA + Custom XML Integration:");
1873
1874 // VBA with multiple modules
1875 let vba_project = VbaProjectPart::new()
1876 .add_module(VbaModule::new("AutoRun", r#"
1877Sub Auto_Open()
1878 MsgBox "Welcome to the presentation!"
1879End Sub
1880
1881Sub NavigateToSlide(slideNum As Integer)
1882 SlideShowWindows(1).View.GotoSlide slideNum
1883End Sub
1884"#))
1885 .add_module(VbaModule::new("DataHelpers", r#"
1886Function GetCustomData(key As String) As String
1887 ' Read from Custom XML part
1888 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1889End Function
1890"#))
1891 .add_module(VbaModule::class("SlideController", r#"
1892Private currentSlide As Integer
1893
1894Public Sub NextSlide()
1895 currentSlide = currentSlide + 1
1896 NavigateToSlide currentSlide
1897End Sub
1898"#));
1899 println!(" │ ├── VBA Project:");
1900 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1901 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1902 println!(" │ │ └── SlideController: Class for navigation");
1903
1904 // Custom XML with structured data
1905 let app_config = CustomXmlPart::new(1, "presentationConfig")
1906 .namespace("http://company.com/pptx/config")
1907 .property("version", "2.1.0")
1908 .property("author", "Demo User")
1909 .property("department", "Engineering")
1910 .property("confidentiality", "Internal")
1911 .property("lastModified", "2024-01-15T10:30:00Z");
1912 let config_xml = app_config.to_xml()?;
1913 println!(" │ └── Custom XML:");
1914 println!(" │ ├── Namespace: http://company.com/pptx/config");
1915 println!(" │ ├── Properties: version, author, department, etc.");
1916 println!(" │ └── XML: {} bytes", config_xml.len());
1917
1918 // -------------------------------------------------------------------------
1919 // Embedded Fonts with Variants
1920 // -------------------------------------------------------------------------
1921 println!(" ├── Embedded Font Collection:");
1922 let mut font_collection = EmbeddedFontCollection::new();
1923 font_collection.add("Corporate Sans", vec![0; 1000]);
1924 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1925 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1926 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1927 font_collection.add("Code Mono", vec![0; 800]);
1928 let fonts_xml = font_collection.to_xml();
1929 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1930 println!(" │ ├── Code Mono: Regular");
1931 println!(" │ ├── Total: {} font files", font_collection.len());
1932 println!(" │ └── XML: {} bytes", fonts_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Handout with Full Configuration
1936 // -------------------------------------------------------------------------
1937 println!(" └── Handout Master Configuration:");
1938 let handout = HandoutMasterPart::new()
1939 .layout(HandoutLayout::SlidesPerPage6)
1940 .header("Q1 2024 Strategy Review")
1941 .footer("Confidential - Internal Use Only");
1942 let handout_xml = handout.to_xml()?;
1943 println!(" ├── Layout: 6 slides per page");
1944 println!(" ├── Header: Q1 2024 Strategy Review");
1945 println!(" ├── Footer: Confidential - Internal Use Only");
1946 println!(" └── XML: {} bytes", handout_xml.len());
1947
1948 // =========================================================================
1949 // Summary
1950 // =========================================================================
1951 println!("\n╔══════════════════════════════════════════════════════════════╗");
1952 println!("║ Element Coverage Summary ║");
1953 println!("╠══════════════════════════════════════════════════════════════╣");
1954 println!("║ LAYOUTS (6 types): ║");
1955 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1956 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1957 println!("╠══════════════════════════════════════════════════════════════╣");
1958 println!("║ TEXT FORMATTING: ║");
1959 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1960 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1961 println!("╠══════════════════════════════════════════════════════════════╣");
1962 println!("║ TABLES: ║");
1963 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1964 println!("║ ✓ Header styling ✓ Position control ║");
1965 println!("╠══════════════════════════════════════════════════════════════╣");
1966 println!("║ CHARTS: ║");
1967 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1968 println!("║ ✓ Multiple series ✓ Categories ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ SHAPES: ║");
1971 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1972 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1973 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1974 println!("╠══════════════════════════════════════════════════════════════╣");
1975 println!("║ CONNECTORS (NEW): ║");
1976 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1977 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1978 println!("╠══════════════════════════════════════════════════════════════╣");
1979 println!("║ IMAGES: ║");
1980 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ PACKAGE: ║");
1983 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
1984 println!("╠══════════════════════════════════════════════════════════════╣");
1985 println!("║ PARTS API (NEW): ║");
1986 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
1987 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
1988 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
1989 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ ELEMENTS API: ║");
1992 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
1993 println!("║ ✓ Position ✓ Size ✓ Transform ║");
1994 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
1995 println!("╠══════════════════════════════════════════════════════════════╣");
1996 println!("║ ADVANCED FEATURES (NEW): ║");
1997 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
1998 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
1999 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2000 println!("║ ✓ Custom XML ✓ Handout Master ║");
2001 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2002 println!("╠══════════════════════════════════════════════════════════════╣");
2003 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2004 slides.len(), pptx_data.len() / 1024);
2005 println!("╚══════════════════════════════════════════════════════════════╝");
2006
2007 Ok(())
2008}Trait Implementations§
Source§impl Clone for TableRowPart
impl Clone for TableRowPart
Source§fn clone(&self) -> TableRowPart
fn clone(&self) -> TableRowPart
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for TableRowPart
impl Debug for TableRowPart
Auto Trait Implementations§
impl Freeze for TableRowPart
impl RefUnwindSafe for TableRowPart
impl Send for TableRowPart
impl Sync for TableRowPart
impl Unpin for TableRowPart
impl UnwindSafe for TableRowPart
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more