pub struct TableCell {Show 15 fields
pub text: String,
pub bold: bool,
pub italic: bool,
pub underline: bool,
pub text_color: Option<String>,
pub background_color: Option<String>,
pub font_size: Option<u32>,
pub font_family: Option<String>,
pub align: CellAlign,
pub valign: CellVAlign,
pub wrap_text: bool,
pub row_span: u32,
pub col_span: u32,
pub v_merge: bool,
pub h_merge: bool,
}Expand description
Table cell content
Fields§
§text: String§bold: bool§italic: bool§underline: bool§text_color: Option<String>§background_color: Option<String>§font_size: Option<u32>§font_family: Option<String>§align: CellAlign§valign: CellVAlign§wrap_text: bool§row_span: u32§col_span: u32§v_merge: bool§h_merge: boolImplementations§
Source§impl TableCell
impl TableCell
Sourcepub fn new(text: &str) -> Self
pub fn new(text: &str) -> Self
Create a new table cell
Examples found in repository?
29fn create_employee_table() -> Table {
30 let header_cells = vec![
31 TableCell::new("Name").bold().background_color("4F81BD"),
32 TableCell::new("Department").bold().background_color("4F81BD"),
33 TableCell::new("Status").bold().background_color("4F81BD"),
34 ];
35 let header_row = TableRow::new(header_cells);
36
37 let rows = vec![
38 TableRow::new(vec![
39 TableCell::new("Alice Johnson"),
40 TableCell::new("Engineering"),
41 TableCell::new("Active"),
42 ]),
43 TableRow::new(vec![
44 TableCell::new("Bob Smith"),
45 TableCell::new("Sales"),
46 TableCell::new("Active"),
47 ]),
48 TableRow::new(vec![
49 TableCell::new("Carol Davis"),
50 TableCell::new("Marketing"),
51 TableCell::new("On Leave"),
52 ]),
53 TableRow::new(vec![
54 TableCell::new("David Wilson"),
55 TableCell::new("Engineering"),
56 TableCell::new("Active"),
57 ]),
58 TableRow::new(vec![
59 TableCell::new("Emma Brown"),
60 TableCell::new("HR"),
61 TableCell::new("Active"),
62 ]),
63 ];
64
65 Table::new(
66 vec![vec![header_row], rows].concat(),
67 vec![2000000, 2500000, 1500000],
68 500000,
69 1500000,
70 )
71}
72
73fn create_sales_table() -> Table {
74 let header_cells = vec![
75 TableCell::new("Product").bold().background_color("003366"),
76 TableCell::new("Revenue").bold().background_color("003366"),
77 TableCell::new("Growth").bold().background_color("003366"),
78 ];
79 let header_row = TableRow::new(header_cells);
80
81 let rows = vec![
82 TableRow::new(vec![
83 TableCell::new("Cloud Services"),
84 TableCell::new("$450K"),
85 TableCell::new("+28%"),
86 ]),
87 TableRow::new(vec![
88 TableCell::new("Enterprise Suite"),
89 TableCell::new("$320K"),
90 TableCell::new("+15%"),
91 ]),
92 TableRow::new(vec![
93 TableCell::new("Developer Tools"),
94 TableCell::new("$280K"),
95 TableCell::new("+42%"),
96 ]),
97 TableRow::new(vec![
98 TableCell::new("Mobile App"),
99 TableCell::new("$195K"),
100 TableCell::new("+35%"),
101 ]),
102 TableRow::new(vec![
103 TableCell::new("Support Services"),
104 TableCell::new("$155K"),
105 TableCell::new("+12%"),
106 ]),
107 ];
108
109 Table::new(
110 vec![vec![header_row], rows].concat(),
111 vec![2200000, 2000000, 1800000],
112 500000,
113 1500000,
114 )
115}
116
117fn create_quarterly_table() -> Table {
118 let header_cells = vec![
119 TableCell::new("Quarter").bold().background_color("1F497D"),
120 TableCell::new("Revenue").bold().background_color("1F497D"),
121 TableCell::new("Profit").bold().background_color("1F497D"),
122 ];
123 let header_row = TableRow::new(header_cells);
124
125 let q1_cells = vec![
126 TableCell::new("Q1 2025"),
127 TableCell::new("$450K"),
128 TableCell::new("$90K"),
129 ];
130 let q1 = TableRow::new(q1_cells);
131
132 let q2_cells = vec![
133 TableCell::new("Q2 2025"),
134 TableCell::new("$520K"),
135 TableCell::new("$110K"),
136 ];
137 let q2 = TableRow::new(q2_cells);
138
139 let q3_cells = vec![
140 TableCell::new("Q3 2025"),
141 TableCell::new("$580K"),
142 TableCell::new("$130K"),
143 ];
144 let q3 = TableRow::new(q3_cells);
145
146 Table::new(
147 vec![header_row, q1, q2, q3],
148 vec![2000000, 2000000, 2000000],
149 500000,
150 1500000,
151 )
152}More examples
81fn create_styled_table_example() -> Result<(), Box<dyn std::error::Error>> {
82 let header_cells = vec![
83 TableCell::new("Name").bold().background_color("003366"),
84 TableCell::new("Age").bold().background_color("003366"),
85 TableCell::new("City").bold().background_color("003366"),
86 ];
87 let header_row = TableRow::new(header_cells);
88
89 let data_rows = vec![
90 TableRow::new(vec![
91 TableCell::new("Alice"),
92 TableCell::new("30"),
93 TableCell::new("NYC"),
94 ]),
95 TableRow::new(vec![
96 TableCell::new("Bob"),
97 TableCell::new("28"),
98 TableCell::new("LA"),
99 ]),
100 TableRow::new(vec![
101 TableCell::new("Carol"),
102 TableCell::new("35"),
103 TableCell::new("Chicago"),
104 ]),
105 ];
106
107 let table = Table::new(
108 vec![vec![header_row], data_rows].concat(),
109 vec![1500000, 1500000, 1500000],
110 500000,
111 1500000,
112 );
113
114 let slides = vec![
115 SlideContent::new("Styled Table")
116 .title_bold(true)
117 .title_color("003366")
118 .add_bullet("Table with formatting"),
119 SlideContent::new("People Data")
120 .table(table),
121 ];
122
123 let pptx_data = create_pptx_with_content("Styled Table", slides)?;
124 fs::write("examples/output/styled_table.pptx", pptx_data)?;
125 Ok(())
126}
127
128fn create_data_table_example() -> Result<(), Box<dyn std::error::Error>> {
129 let header_cells = vec![
130 TableCell::new("Product").bold().background_color("1F497D"),
131 TableCell::new("Revenue").bold().background_color("1F497D"),
132 TableCell::new("Growth").bold().background_color("1F497D"),
133 ];
134 let header_row = TableRow::new(header_cells);
135
136 let data_rows = vec![
137 TableRow::new(vec![
138 TableCell::new("Product A"),
139 TableCell::new("$100K"),
140 TableCell::new("+15%"),
141 ]),
142 TableRow::new(vec![
143 TableCell::new("Product B"),
144 TableCell::new("$150K"),
145 TableCell::new("+22%"),
146 ]),
147 TableRow::new(vec![
148 TableCell::new("Product C"),
149 TableCell::new("$200K"),
150 TableCell::new("+18%"),
151 ]),
152 ];
153
154 let table = Table::new(
155 vec![vec![header_row], data_rows].concat(),
156 vec![2000000, 2000000, 1500000],
157 457200,
158 1400000,
159 );
160
161 let slides = vec![
162 SlideContent::new("Sales Data Table")
163 .title_bold(true)
164 .title_size(48)
165 .add_bullet("Quarterly sales figures"),
166 SlideContent::new("Q1 2025 Sales")
167 .table(table),
168 SlideContent::new("Summary")
169 .content_bold(true)
170 .add_bullet("Total Revenue: $450K")
171 .add_bullet("Average Growth: +18.3%")
172 .add_bullet("Best Performer: Product C"),
173 ];
174
175 let pptx_data = create_pptx_with_content("Sales Data", slides)?;
176 fs::write("examples/output/data_table.pptx", pptx_data)?;
177 Ok(())
178}
179
180fn create_multiple_tables_example() -> Result<(), Box<dyn std::error::Error>> {
181 // Table 1: Employees
182 let emp_header = TableRow::new(vec![
183 TableCell::new("ID").bold().background_color("4F81BD"),
184 TableCell::new("Name").bold().background_color("4F81BD"),
185 TableCell::new("Department").bold().background_color("4F81BD"),
186 ]);
187 let emp_rows = vec![
188 TableRow::new(vec![
189 TableCell::new("001"),
190 TableCell::new("Alice"),
191 TableCell::new("Engineering"),
192 ]),
193 TableRow::new(vec![
194 TableCell::new("002"),
195 TableCell::new("Bob"),
196 TableCell::new("Sales"),
197 ]),
198 TableRow::new(vec![
199 TableCell::new("003"),
200 TableCell::new("Carol"),
201 TableCell::new("Marketing"),
202 ]),
203 ];
204 let emp_table = Table::new(
205 vec![vec![emp_header], emp_rows].concat(),
206 vec![1000000, 2000000, 2000000],
207 500000,
208 1500000,
209 );
210
211 // Table 2: Projects
212 let proj_header = TableRow::new(vec![
213 TableCell::new("Project").bold().background_color("003366"),
214 TableCell::new("Status").bold().background_color("003366"),
215 TableCell::new("Owner").bold().background_color("003366"),
216 ]);
217 let proj_rows = vec![
218 TableRow::new(vec![
219 TableCell::new("Project A"),
220 TableCell::new("In Progress"),
221 TableCell::new("Alice"),
222 ]),
223 TableRow::new(vec![
224 TableCell::new("Project B"),
225 TableCell::new("Completed"),
226 TableCell::new("Bob"),
227 ]),
228 TableRow::new(vec![
229 TableCell::new("Project C"),
230 TableCell::new("Planning"),
231 TableCell::new("Carol"),
232 ]),
233 ];
234 let proj_table = Table::new(
235 vec![vec![proj_header], proj_rows].concat(),
236 vec![2000000, 2000000, 1500000],
237 500000,
238 1500000,
239 );
240
241 let slides = vec![
242 SlideContent::new("Multiple Tables")
243 .title_bold(true)
244 .add_bullet("Slide with multiple tables"),
245 SlideContent::new("Table 1: Employees")
246 .table(emp_table),
247 SlideContent::new("Table 2: Projects")
248 .table(proj_table),
249 SlideContent::new("Summary")
250 .add_bullet("Total Employees: 3")
251 .add_bullet("Active Projects: 3")
252 .add_bullet("Completion Rate: 33%"),
253 ];
254
255 let pptx_data = create_pptx_with_content("Multiple Tables", slides)?;
256 fs::write("examples/output/multiple_tables.pptx", pptx_data)?;
257 Ok(())
258}
259
260/// Helper function to demonstrate table creation
261#[allow(dead_code)]
262fn create_table_structure() -> Table {
263 // Create table using builder
264 TableBuilder::new(vec![1000000, 1000000, 1000000])
265 .position(500000, 1000000)
266 .add_simple_row(vec!["Header 1", "Header 2", "Header 3"])
267 .add_simple_row(vec!["Data 1", "Data 2", "Data 3"])
268 .add_simple_row(vec!["Data 4", "Data 5", "Data 6"])
269 .build()
270}
271
272/// Helper function to demonstrate styled table
273#[allow(dead_code)]
274fn create_styled_table() -> Table {
275 let header_cells = vec![
276 TableCell::new("Name").bold().background_color("003366"),
277 TableCell::new("Age").bold().background_color("003366"),
278 TableCell::new("City").bold().background_color("003366"),
279 ];
280 let header_row = TableRow::new(header_cells);
281
282 let data_cells = vec![
283 TableCell::new("Alice"),
284 TableCell::new("30"),
285 TableCell::new("NYC"),
286 ];
287 let data_row = TableRow::new(data_cells);
288
289 Table::new(
290 vec![header_row, data_row],
291 vec![1000000, 1000000, 1000000],
292 500000,
293 1000000,
294 )
295}33fn create_text_formatting_table() -> Table {
34 let header_cells = vec![
35 TableCell::new("Style").bold().background_color("4F81BD"),
36 TableCell::new("Example").bold().background_color("4F81BD"),
37 TableCell::new("Description").bold().background_color("4F81BD"),
38 ];
39 let header_row = TableRow::new(header_cells);
40
41 let rows = vec![
42 TableRow::new(vec![
43 TableCell::new("Bold"),
44 TableCell::new("Bold Text").bold(),
45 TableCell::new("Text with bold formatting"),
46 ]),
47 TableRow::new(vec![
48 TableCell::new("Italic"),
49 TableCell::new("Italic Text").italic(),
50 TableCell::new("Text with italic formatting"),
51 ]),
52 TableRow::new(vec![
53 TableCell::new("Underline"),
54 TableCell::new("Underlined Text").underline(),
55 TableCell::new("Text with underline formatting"),
56 ]),
57 TableRow::new(vec![
58 TableCell::new("Bold + Italic"),
59 TableCell::new("Bold Italic Text").bold().italic(),
60 TableCell::new("Text with both bold and italic"),
61 ]),
62 TableRow::new(vec![
63 TableCell::new("All Three"),
64 TableCell::new("Bold Italic Underlined").bold().italic().underline(),
65 TableCell::new("Text with all formatting options"),
66 ]),
67 ];
68
69 Table::new(
70 vec![vec![header_row], rows].concat(),
71 vec![2000000, 3000000, 3000000],
72 500000,
73 1500000,
74 )
75}
76
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}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}Sourcepub fn bold(self) -> Self
pub fn bold(self) -> Self
Set cell text as bold
Examples found in repository?
29fn create_employee_table() -> Table {
30 let header_cells = vec![
31 TableCell::new("Name").bold().background_color("4F81BD"),
32 TableCell::new("Department").bold().background_color("4F81BD"),
33 TableCell::new("Status").bold().background_color("4F81BD"),
34 ];
35 let header_row = TableRow::new(header_cells);
36
37 let rows = vec![
38 TableRow::new(vec![
39 TableCell::new("Alice Johnson"),
40 TableCell::new("Engineering"),
41 TableCell::new("Active"),
42 ]),
43 TableRow::new(vec![
44 TableCell::new("Bob Smith"),
45 TableCell::new("Sales"),
46 TableCell::new("Active"),
47 ]),
48 TableRow::new(vec![
49 TableCell::new("Carol Davis"),
50 TableCell::new("Marketing"),
51 TableCell::new("On Leave"),
52 ]),
53 TableRow::new(vec![
54 TableCell::new("David Wilson"),
55 TableCell::new("Engineering"),
56 TableCell::new("Active"),
57 ]),
58 TableRow::new(vec![
59 TableCell::new("Emma Brown"),
60 TableCell::new("HR"),
61 TableCell::new("Active"),
62 ]),
63 ];
64
65 Table::new(
66 vec![vec![header_row], rows].concat(),
67 vec![2000000, 2500000, 1500000],
68 500000,
69 1500000,
70 )
71}
72
73fn create_sales_table() -> Table {
74 let header_cells = vec![
75 TableCell::new("Product").bold().background_color("003366"),
76 TableCell::new("Revenue").bold().background_color("003366"),
77 TableCell::new("Growth").bold().background_color("003366"),
78 ];
79 let header_row = TableRow::new(header_cells);
80
81 let rows = vec![
82 TableRow::new(vec![
83 TableCell::new("Cloud Services"),
84 TableCell::new("$450K"),
85 TableCell::new("+28%"),
86 ]),
87 TableRow::new(vec![
88 TableCell::new("Enterprise Suite"),
89 TableCell::new("$320K"),
90 TableCell::new("+15%"),
91 ]),
92 TableRow::new(vec![
93 TableCell::new("Developer Tools"),
94 TableCell::new("$280K"),
95 TableCell::new("+42%"),
96 ]),
97 TableRow::new(vec![
98 TableCell::new("Mobile App"),
99 TableCell::new("$195K"),
100 TableCell::new("+35%"),
101 ]),
102 TableRow::new(vec![
103 TableCell::new("Support Services"),
104 TableCell::new("$155K"),
105 TableCell::new("+12%"),
106 ]),
107 ];
108
109 Table::new(
110 vec![vec![header_row], rows].concat(),
111 vec![2200000, 2000000, 1800000],
112 500000,
113 1500000,
114 )
115}
116
117fn create_quarterly_table() -> Table {
118 let header_cells = vec![
119 TableCell::new("Quarter").bold().background_color("1F497D"),
120 TableCell::new("Revenue").bold().background_color("1F497D"),
121 TableCell::new("Profit").bold().background_color("1F497D"),
122 ];
123 let header_row = TableRow::new(header_cells);
124
125 let q1_cells = vec![
126 TableCell::new("Q1 2025"),
127 TableCell::new("$450K"),
128 TableCell::new("$90K"),
129 ];
130 let q1 = TableRow::new(q1_cells);
131
132 let q2_cells = vec![
133 TableCell::new("Q2 2025"),
134 TableCell::new("$520K"),
135 TableCell::new("$110K"),
136 ];
137 let q2 = TableRow::new(q2_cells);
138
139 let q3_cells = vec![
140 TableCell::new("Q3 2025"),
141 TableCell::new("$580K"),
142 TableCell::new("$130K"),
143 ];
144 let q3 = TableRow::new(q3_cells);
145
146 Table::new(
147 vec![header_row, q1, q2, q3],
148 vec![2000000, 2000000, 2000000],
149 500000,
150 1500000,
151 )
152}More examples
81fn create_styled_table_example() -> Result<(), Box<dyn std::error::Error>> {
82 let header_cells = vec![
83 TableCell::new("Name").bold().background_color("003366"),
84 TableCell::new("Age").bold().background_color("003366"),
85 TableCell::new("City").bold().background_color("003366"),
86 ];
87 let header_row = TableRow::new(header_cells);
88
89 let data_rows = vec![
90 TableRow::new(vec![
91 TableCell::new("Alice"),
92 TableCell::new("30"),
93 TableCell::new("NYC"),
94 ]),
95 TableRow::new(vec![
96 TableCell::new("Bob"),
97 TableCell::new("28"),
98 TableCell::new("LA"),
99 ]),
100 TableRow::new(vec![
101 TableCell::new("Carol"),
102 TableCell::new("35"),
103 TableCell::new("Chicago"),
104 ]),
105 ];
106
107 let table = Table::new(
108 vec![vec![header_row], data_rows].concat(),
109 vec![1500000, 1500000, 1500000],
110 500000,
111 1500000,
112 );
113
114 let slides = vec![
115 SlideContent::new("Styled Table")
116 .title_bold(true)
117 .title_color("003366")
118 .add_bullet("Table with formatting"),
119 SlideContent::new("People Data")
120 .table(table),
121 ];
122
123 let pptx_data = create_pptx_with_content("Styled Table", slides)?;
124 fs::write("examples/output/styled_table.pptx", pptx_data)?;
125 Ok(())
126}
127
128fn create_data_table_example() -> Result<(), Box<dyn std::error::Error>> {
129 let header_cells = vec![
130 TableCell::new("Product").bold().background_color("1F497D"),
131 TableCell::new("Revenue").bold().background_color("1F497D"),
132 TableCell::new("Growth").bold().background_color("1F497D"),
133 ];
134 let header_row = TableRow::new(header_cells);
135
136 let data_rows = vec![
137 TableRow::new(vec![
138 TableCell::new("Product A"),
139 TableCell::new("$100K"),
140 TableCell::new("+15%"),
141 ]),
142 TableRow::new(vec![
143 TableCell::new("Product B"),
144 TableCell::new("$150K"),
145 TableCell::new("+22%"),
146 ]),
147 TableRow::new(vec![
148 TableCell::new("Product C"),
149 TableCell::new("$200K"),
150 TableCell::new("+18%"),
151 ]),
152 ];
153
154 let table = Table::new(
155 vec![vec![header_row], data_rows].concat(),
156 vec![2000000, 2000000, 1500000],
157 457200,
158 1400000,
159 );
160
161 let slides = vec![
162 SlideContent::new("Sales Data Table")
163 .title_bold(true)
164 .title_size(48)
165 .add_bullet("Quarterly sales figures"),
166 SlideContent::new("Q1 2025 Sales")
167 .table(table),
168 SlideContent::new("Summary")
169 .content_bold(true)
170 .add_bullet("Total Revenue: $450K")
171 .add_bullet("Average Growth: +18.3%")
172 .add_bullet("Best Performer: Product C"),
173 ];
174
175 let pptx_data = create_pptx_with_content("Sales Data", slides)?;
176 fs::write("examples/output/data_table.pptx", pptx_data)?;
177 Ok(())
178}
179
180fn create_multiple_tables_example() -> Result<(), Box<dyn std::error::Error>> {
181 // Table 1: Employees
182 let emp_header = TableRow::new(vec![
183 TableCell::new("ID").bold().background_color("4F81BD"),
184 TableCell::new("Name").bold().background_color("4F81BD"),
185 TableCell::new("Department").bold().background_color("4F81BD"),
186 ]);
187 let emp_rows = vec![
188 TableRow::new(vec![
189 TableCell::new("001"),
190 TableCell::new("Alice"),
191 TableCell::new("Engineering"),
192 ]),
193 TableRow::new(vec![
194 TableCell::new("002"),
195 TableCell::new("Bob"),
196 TableCell::new("Sales"),
197 ]),
198 TableRow::new(vec![
199 TableCell::new("003"),
200 TableCell::new("Carol"),
201 TableCell::new("Marketing"),
202 ]),
203 ];
204 let emp_table = Table::new(
205 vec![vec![emp_header], emp_rows].concat(),
206 vec![1000000, 2000000, 2000000],
207 500000,
208 1500000,
209 );
210
211 // Table 2: Projects
212 let proj_header = TableRow::new(vec![
213 TableCell::new("Project").bold().background_color("003366"),
214 TableCell::new("Status").bold().background_color("003366"),
215 TableCell::new("Owner").bold().background_color("003366"),
216 ]);
217 let proj_rows = vec![
218 TableRow::new(vec![
219 TableCell::new("Project A"),
220 TableCell::new("In Progress"),
221 TableCell::new("Alice"),
222 ]),
223 TableRow::new(vec![
224 TableCell::new("Project B"),
225 TableCell::new("Completed"),
226 TableCell::new("Bob"),
227 ]),
228 TableRow::new(vec![
229 TableCell::new("Project C"),
230 TableCell::new("Planning"),
231 TableCell::new("Carol"),
232 ]),
233 ];
234 let proj_table = Table::new(
235 vec![vec![proj_header], proj_rows].concat(),
236 vec![2000000, 2000000, 1500000],
237 500000,
238 1500000,
239 );
240
241 let slides = vec![
242 SlideContent::new("Multiple Tables")
243 .title_bold(true)
244 .add_bullet("Slide with multiple tables"),
245 SlideContent::new("Table 1: Employees")
246 .table(emp_table),
247 SlideContent::new("Table 2: Projects")
248 .table(proj_table),
249 SlideContent::new("Summary")
250 .add_bullet("Total Employees: 3")
251 .add_bullet("Active Projects: 3")
252 .add_bullet("Completion Rate: 33%"),
253 ];
254
255 let pptx_data = create_pptx_with_content("Multiple Tables", slides)?;
256 fs::write("examples/output/multiple_tables.pptx", pptx_data)?;
257 Ok(())
258}
259
260/// Helper function to demonstrate table creation
261#[allow(dead_code)]
262fn create_table_structure() -> Table {
263 // Create table using builder
264 TableBuilder::new(vec![1000000, 1000000, 1000000])
265 .position(500000, 1000000)
266 .add_simple_row(vec!["Header 1", "Header 2", "Header 3"])
267 .add_simple_row(vec!["Data 1", "Data 2", "Data 3"])
268 .add_simple_row(vec!["Data 4", "Data 5", "Data 6"])
269 .build()
270}
271
272/// Helper function to demonstrate styled table
273#[allow(dead_code)]
274fn create_styled_table() -> Table {
275 let header_cells = vec![
276 TableCell::new("Name").bold().background_color("003366"),
277 TableCell::new("Age").bold().background_color("003366"),
278 TableCell::new("City").bold().background_color("003366"),
279 ];
280 let header_row = TableRow::new(header_cells);
281
282 let data_cells = vec![
283 TableCell::new("Alice"),
284 TableCell::new("30"),
285 TableCell::new("NYC"),
286 ];
287 let data_row = TableRow::new(data_cells);
288
289 Table::new(
290 vec![header_row, data_row],
291 vec![1000000, 1000000, 1000000],
292 500000,
293 1000000,
294 )
295}33fn create_text_formatting_table() -> Table {
34 let header_cells = vec![
35 TableCell::new("Style").bold().background_color("4F81BD"),
36 TableCell::new("Example").bold().background_color("4F81BD"),
37 TableCell::new("Description").bold().background_color("4F81BD"),
38 ];
39 let header_row = TableRow::new(header_cells);
40
41 let rows = vec![
42 TableRow::new(vec![
43 TableCell::new("Bold"),
44 TableCell::new("Bold Text").bold(),
45 TableCell::new("Text with bold formatting"),
46 ]),
47 TableRow::new(vec![
48 TableCell::new("Italic"),
49 TableCell::new("Italic Text").italic(),
50 TableCell::new("Text with italic formatting"),
51 ]),
52 TableRow::new(vec![
53 TableCell::new("Underline"),
54 TableCell::new("Underlined Text").underline(),
55 TableCell::new("Text with underline formatting"),
56 ]),
57 TableRow::new(vec![
58 TableCell::new("Bold + Italic"),
59 TableCell::new("Bold Italic Text").bold().italic(),
60 TableCell::new("Text with both bold and italic"),
61 ]),
62 TableRow::new(vec![
63 TableCell::new("All Three"),
64 TableCell::new("Bold Italic Underlined").bold().italic().underline(),
65 TableCell::new("Text with all formatting options"),
66 ]),
67 ];
68
69 Table::new(
70 vec![vec![header_row], rows].concat(),
71 vec![2000000, 3000000, 3000000],
72 500000,
73 1500000,
74 )
75}
76
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}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}Sourcepub fn italic(self) -> Self
pub fn italic(self) -> Self
Set cell text as italic
Examples found in repository?
33fn create_text_formatting_table() -> Table {
34 let header_cells = vec![
35 TableCell::new("Style").bold().background_color("4F81BD"),
36 TableCell::new("Example").bold().background_color("4F81BD"),
37 TableCell::new("Description").bold().background_color("4F81BD"),
38 ];
39 let header_row = TableRow::new(header_cells);
40
41 let rows = vec![
42 TableRow::new(vec![
43 TableCell::new("Bold"),
44 TableCell::new("Bold Text").bold(),
45 TableCell::new("Text with bold formatting"),
46 ]),
47 TableRow::new(vec![
48 TableCell::new("Italic"),
49 TableCell::new("Italic Text").italic(),
50 TableCell::new("Text with italic formatting"),
51 ]),
52 TableRow::new(vec![
53 TableCell::new("Underline"),
54 TableCell::new("Underlined Text").underline(),
55 TableCell::new("Text with underline formatting"),
56 ]),
57 TableRow::new(vec![
58 TableCell::new("Bold + Italic"),
59 TableCell::new("Bold Italic Text").bold().italic(),
60 TableCell::new("Text with both bold and italic"),
61 ]),
62 TableRow::new(vec![
63 TableCell::new("All Three"),
64 TableCell::new("Bold Italic Underlined").bold().italic().underline(),
65 TableCell::new("Text with all formatting options"),
66 ]),
67 ];
68
69 Table::new(
70 vec![vec![header_row], rows].concat(),
71 vec![2000000, 3000000, 3000000],
72 500000,
73 1500000,
74 )
75}
76
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}Sourcepub fn underline(self) -> Self
pub fn underline(self) -> Self
Set cell text as underlined
Examples found in repository?
33fn create_text_formatting_table() -> Table {
34 let header_cells = vec![
35 TableCell::new("Style").bold().background_color("4F81BD"),
36 TableCell::new("Example").bold().background_color("4F81BD"),
37 TableCell::new("Description").bold().background_color("4F81BD"),
38 ];
39 let header_row = TableRow::new(header_cells);
40
41 let rows = vec![
42 TableRow::new(vec![
43 TableCell::new("Bold"),
44 TableCell::new("Bold Text").bold(),
45 TableCell::new("Text with bold formatting"),
46 ]),
47 TableRow::new(vec![
48 TableCell::new("Italic"),
49 TableCell::new("Italic Text").italic(),
50 TableCell::new("Text with italic formatting"),
51 ]),
52 TableRow::new(vec![
53 TableCell::new("Underline"),
54 TableCell::new("Underlined Text").underline(),
55 TableCell::new("Text with underline formatting"),
56 ]),
57 TableRow::new(vec![
58 TableCell::new("Bold + Italic"),
59 TableCell::new("Bold Italic Text").bold().italic(),
60 TableCell::new("Text with both bold and italic"),
61 ]),
62 TableRow::new(vec![
63 TableCell::new("All Three"),
64 TableCell::new("Bold Italic Underlined").bold().italic().underline(),
65 TableCell::new("Text with all formatting options"),
66 ]),
67 ];
68
69 Table::new(
70 vec![vec![header_row], rows].concat(),
71 vec![2000000, 3000000, 3000000],
72 500000,
73 1500000,
74 )
75}
76
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}Sourcepub fn text_color(self, color: &str) -> Self
pub fn text_color(self, color: &str) -> Self
Set cell text color (RGB hex format, e.g., “FF0000” or “#FF0000”)
Examples found in repository?
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}More examples
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}Sourcepub fn background_color(self, color: &str) -> Self
pub fn background_color(self, color: &str) -> Self
Set cell background color (RGB hex format, e.g., “FF0000” or “#FF0000”)
Examples found in repository?
29fn create_employee_table() -> Table {
30 let header_cells = vec![
31 TableCell::new("Name").bold().background_color("4F81BD"),
32 TableCell::new("Department").bold().background_color("4F81BD"),
33 TableCell::new("Status").bold().background_color("4F81BD"),
34 ];
35 let header_row = TableRow::new(header_cells);
36
37 let rows = vec![
38 TableRow::new(vec![
39 TableCell::new("Alice Johnson"),
40 TableCell::new("Engineering"),
41 TableCell::new("Active"),
42 ]),
43 TableRow::new(vec![
44 TableCell::new("Bob Smith"),
45 TableCell::new("Sales"),
46 TableCell::new("Active"),
47 ]),
48 TableRow::new(vec![
49 TableCell::new("Carol Davis"),
50 TableCell::new("Marketing"),
51 TableCell::new("On Leave"),
52 ]),
53 TableRow::new(vec![
54 TableCell::new("David Wilson"),
55 TableCell::new("Engineering"),
56 TableCell::new("Active"),
57 ]),
58 TableRow::new(vec![
59 TableCell::new("Emma Brown"),
60 TableCell::new("HR"),
61 TableCell::new("Active"),
62 ]),
63 ];
64
65 Table::new(
66 vec![vec![header_row], rows].concat(),
67 vec![2000000, 2500000, 1500000],
68 500000,
69 1500000,
70 )
71}
72
73fn create_sales_table() -> Table {
74 let header_cells = vec![
75 TableCell::new("Product").bold().background_color("003366"),
76 TableCell::new("Revenue").bold().background_color("003366"),
77 TableCell::new("Growth").bold().background_color("003366"),
78 ];
79 let header_row = TableRow::new(header_cells);
80
81 let rows = vec![
82 TableRow::new(vec![
83 TableCell::new("Cloud Services"),
84 TableCell::new("$450K"),
85 TableCell::new("+28%"),
86 ]),
87 TableRow::new(vec![
88 TableCell::new("Enterprise Suite"),
89 TableCell::new("$320K"),
90 TableCell::new("+15%"),
91 ]),
92 TableRow::new(vec![
93 TableCell::new("Developer Tools"),
94 TableCell::new("$280K"),
95 TableCell::new("+42%"),
96 ]),
97 TableRow::new(vec![
98 TableCell::new("Mobile App"),
99 TableCell::new("$195K"),
100 TableCell::new("+35%"),
101 ]),
102 TableRow::new(vec![
103 TableCell::new("Support Services"),
104 TableCell::new("$155K"),
105 TableCell::new("+12%"),
106 ]),
107 ];
108
109 Table::new(
110 vec![vec![header_row], rows].concat(),
111 vec![2200000, 2000000, 1800000],
112 500000,
113 1500000,
114 )
115}
116
117fn create_quarterly_table() -> Table {
118 let header_cells = vec![
119 TableCell::new("Quarter").bold().background_color("1F497D"),
120 TableCell::new("Revenue").bold().background_color("1F497D"),
121 TableCell::new("Profit").bold().background_color("1F497D"),
122 ];
123 let header_row = TableRow::new(header_cells);
124
125 let q1_cells = vec![
126 TableCell::new("Q1 2025"),
127 TableCell::new("$450K"),
128 TableCell::new("$90K"),
129 ];
130 let q1 = TableRow::new(q1_cells);
131
132 let q2_cells = vec![
133 TableCell::new("Q2 2025"),
134 TableCell::new("$520K"),
135 TableCell::new("$110K"),
136 ];
137 let q2 = TableRow::new(q2_cells);
138
139 let q3_cells = vec![
140 TableCell::new("Q3 2025"),
141 TableCell::new("$580K"),
142 TableCell::new("$130K"),
143 ];
144 let q3 = TableRow::new(q3_cells);
145
146 Table::new(
147 vec![header_row, q1, q2, q3],
148 vec![2000000, 2000000, 2000000],
149 500000,
150 1500000,
151 )
152}More examples
81fn create_styled_table_example() -> Result<(), Box<dyn std::error::Error>> {
82 let header_cells = vec![
83 TableCell::new("Name").bold().background_color("003366"),
84 TableCell::new("Age").bold().background_color("003366"),
85 TableCell::new("City").bold().background_color("003366"),
86 ];
87 let header_row = TableRow::new(header_cells);
88
89 let data_rows = vec![
90 TableRow::new(vec![
91 TableCell::new("Alice"),
92 TableCell::new("30"),
93 TableCell::new("NYC"),
94 ]),
95 TableRow::new(vec![
96 TableCell::new("Bob"),
97 TableCell::new("28"),
98 TableCell::new("LA"),
99 ]),
100 TableRow::new(vec![
101 TableCell::new("Carol"),
102 TableCell::new("35"),
103 TableCell::new("Chicago"),
104 ]),
105 ];
106
107 let table = Table::new(
108 vec![vec![header_row], data_rows].concat(),
109 vec![1500000, 1500000, 1500000],
110 500000,
111 1500000,
112 );
113
114 let slides = vec![
115 SlideContent::new("Styled Table")
116 .title_bold(true)
117 .title_color("003366")
118 .add_bullet("Table with formatting"),
119 SlideContent::new("People Data")
120 .table(table),
121 ];
122
123 let pptx_data = create_pptx_with_content("Styled Table", slides)?;
124 fs::write("examples/output/styled_table.pptx", pptx_data)?;
125 Ok(())
126}
127
128fn create_data_table_example() -> Result<(), Box<dyn std::error::Error>> {
129 let header_cells = vec![
130 TableCell::new("Product").bold().background_color("1F497D"),
131 TableCell::new("Revenue").bold().background_color("1F497D"),
132 TableCell::new("Growth").bold().background_color("1F497D"),
133 ];
134 let header_row = TableRow::new(header_cells);
135
136 let data_rows = vec![
137 TableRow::new(vec![
138 TableCell::new("Product A"),
139 TableCell::new("$100K"),
140 TableCell::new("+15%"),
141 ]),
142 TableRow::new(vec![
143 TableCell::new("Product B"),
144 TableCell::new("$150K"),
145 TableCell::new("+22%"),
146 ]),
147 TableRow::new(vec![
148 TableCell::new("Product C"),
149 TableCell::new("$200K"),
150 TableCell::new("+18%"),
151 ]),
152 ];
153
154 let table = Table::new(
155 vec![vec![header_row], data_rows].concat(),
156 vec![2000000, 2000000, 1500000],
157 457200,
158 1400000,
159 );
160
161 let slides = vec![
162 SlideContent::new("Sales Data Table")
163 .title_bold(true)
164 .title_size(48)
165 .add_bullet("Quarterly sales figures"),
166 SlideContent::new("Q1 2025 Sales")
167 .table(table),
168 SlideContent::new("Summary")
169 .content_bold(true)
170 .add_bullet("Total Revenue: $450K")
171 .add_bullet("Average Growth: +18.3%")
172 .add_bullet("Best Performer: Product C"),
173 ];
174
175 let pptx_data = create_pptx_with_content("Sales Data", slides)?;
176 fs::write("examples/output/data_table.pptx", pptx_data)?;
177 Ok(())
178}
179
180fn create_multiple_tables_example() -> Result<(), Box<dyn std::error::Error>> {
181 // Table 1: Employees
182 let emp_header = TableRow::new(vec![
183 TableCell::new("ID").bold().background_color("4F81BD"),
184 TableCell::new("Name").bold().background_color("4F81BD"),
185 TableCell::new("Department").bold().background_color("4F81BD"),
186 ]);
187 let emp_rows = vec![
188 TableRow::new(vec![
189 TableCell::new("001"),
190 TableCell::new("Alice"),
191 TableCell::new("Engineering"),
192 ]),
193 TableRow::new(vec![
194 TableCell::new("002"),
195 TableCell::new("Bob"),
196 TableCell::new("Sales"),
197 ]),
198 TableRow::new(vec![
199 TableCell::new("003"),
200 TableCell::new("Carol"),
201 TableCell::new("Marketing"),
202 ]),
203 ];
204 let emp_table = Table::new(
205 vec![vec![emp_header], emp_rows].concat(),
206 vec![1000000, 2000000, 2000000],
207 500000,
208 1500000,
209 );
210
211 // Table 2: Projects
212 let proj_header = TableRow::new(vec![
213 TableCell::new("Project").bold().background_color("003366"),
214 TableCell::new("Status").bold().background_color("003366"),
215 TableCell::new("Owner").bold().background_color("003366"),
216 ]);
217 let proj_rows = vec![
218 TableRow::new(vec![
219 TableCell::new("Project A"),
220 TableCell::new("In Progress"),
221 TableCell::new("Alice"),
222 ]),
223 TableRow::new(vec![
224 TableCell::new("Project B"),
225 TableCell::new("Completed"),
226 TableCell::new("Bob"),
227 ]),
228 TableRow::new(vec![
229 TableCell::new("Project C"),
230 TableCell::new("Planning"),
231 TableCell::new("Carol"),
232 ]),
233 ];
234 let proj_table = Table::new(
235 vec![vec![proj_header], proj_rows].concat(),
236 vec![2000000, 2000000, 1500000],
237 500000,
238 1500000,
239 );
240
241 let slides = vec![
242 SlideContent::new("Multiple Tables")
243 .title_bold(true)
244 .add_bullet("Slide with multiple tables"),
245 SlideContent::new("Table 1: Employees")
246 .table(emp_table),
247 SlideContent::new("Table 2: Projects")
248 .table(proj_table),
249 SlideContent::new("Summary")
250 .add_bullet("Total Employees: 3")
251 .add_bullet("Active Projects: 3")
252 .add_bullet("Completion Rate: 33%"),
253 ];
254
255 let pptx_data = create_pptx_with_content("Multiple Tables", slides)?;
256 fs::write("examples/output/multiple_tables.pptx", pptx_data)?;
257 Ok(())
258}
259
260/// Helper function to demonstrate table creation
261#[allow(dead_code)]
262fn create_table_structure() -> Table {
263 // Create table using builder
264 TableBuilder::new(vec![1000000, 1000000, 1000000])
265 .position(500000, 1000000)
266 .add_simple_row(vec!["Header 1", "Header 2", "Header 3"])
267 .add_simple_row(vec!["Data 1", "Data 2", "Data 3"])
268 .add_simple_row(vec!["Data 4", "Data 5", "Data 6"])
269 .build()
270}
271
272/// Helper function to demonstrate styled table
273#[allow(dead_code)]
274fn create_styled_table() -> Table {
275 let header_cells = vec![
276 TableCell::new("Name").bold().background_color("003366"),
277 TableCell::new("Age").bold().background_color("003366"),
278 TableCell::new("City").bold().background_color("003366"),
279 ];
280 let header_row = TableRow::new(header_cells);
281
282 let data_cells = vec![
283 TableCell::new("Alice"),
284 TableCell::new("30"),
285 TableCell::new("NYC"),
286 ];
287 let data_row = TableRow::new(data_cells);
288
289 Table::new(
290 vec![header_row, data_row],
291 vec![1000000, 1000000, 1000000],
292 500000,
293 1000000,
294 )
295}33fn create_text_formatting_table() -> Table {
34 let header_cells = vec![
35 TableCell::new("Style").bold().background_color("4F81BD"),
36 TableCell::new("Example").bold().background_color("4F81BD"),
37 TableCell::new("Description").bold().background_color("4F81BD"),
38 ];
39 let header_row = TableRow::new(header_cells);
40
41 let rows = vec![
42 TableRow::new(vec![
43 TableCell::new("Bold"),
44 TableCell::new("Bold Text").bold(),
45 TableCell::new("Text with bold formatting"),
46 ]),
47 TableRow::new(vec![
48 TableCell::new("Italic"),
49 TableCell::new("Italic Text").italic(),
50 TableCell::new("Text with italic formatting"),
51 ]),
52 TableRow::new(vec![
53 TableCell::new("Underline"),
54 TableCell::new("Underlined Text").underline(),
55 TableCell::new("Text with underline formatting"),
56 ]),
57 TableRow::new(vec![
58 TableCell::new("Bold + Italic"),
59 TableCell::new("Bold Italic Text").bold().italic(),
60 TableCell::new("Text with both bold and italic"),
61 ]),
62 TableRow::new(vec![
63 TableCell::new("All Three"),
64 TableCell::new("Bold Italic Underlined").bold().italic().underline(),
65 TableCell::new("Text with all formatting options"),
66 ]),
67 ];
68
69 Table::new(
70 vec![vec![header_row], rows].concat(),
71 vec![2000000, 3000000, 3000000],
72 500000,
73 1500000,
74 )
75}
76
77fn create_color_table() -> Table {
78 let header_cells = vec![
79 TableCell::new("Text Color").bold().background_color("1F497D"),
80 TableCell::new("Background").bold().background_color("1F497D"),
81 TableCell::new("Example").bold().background_color("1F497D"),
82 ];
83 let header_row = TableRow::new(header_cells);
84
85 let rows = vec![
86 TableRow::new(vec![
87 TableCell::new("Red"),
88 TableCell::new("White"),
89 TableCell::new("Red Text").text_color("FF0000").background_color("FFFFFF"),
90 ]),
91 TableRow::new(vec![
92 TableCell::new("Blue"),
93 TableCell::new("Yellow"),
94 TableCell::new("Blue Text").text_color("0000FF").background_color("FFFF00"),
95 ]),
96 TableRow::new(vec![
97 TableCell::new("Green"),
98 TableCell::new("Light Gray"),
99 TableCell::new("Green Text").text_color("00FF00").background_color("E0E0E0"),
100 ]),
101 TableRow::new(vec![
102 TableCell::new("Purple"),
103 TableCell::new("White"),
104 TableCell::new("Purple Text").text_color("800080").background_color("FFFFFF"),
105 ]),
106 ];
107
108 Table::new(
109 vec![vec![header_row], rows].concat(),
110 vec![2000000, 2000000, 4000000],
111 500000,
112 1500000,
113 )
114}
115
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}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}Sourcepub fn font_size(self, size: u32) -> Self
pub fn font_size(self, size: u32) -> Self
Set font size in points
Examples found in repository?
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}More examples
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}Sourcepub fn font_family(self, family: &str) -> Self
pub fn font_family(self, family: &str) -> Self
Set font family name
Examples found in repository?
116fn create_font_table() -> Table {
117 let header_cells = vec![
118 TableCell::new("Font Size").bold().background_color("366092"),
119 TableCell::new("Font Family").bold().background_color("366092"),
120 TableCell::new("Example").bold().background_color("366092"),
121 ];
122 let header_row = TableRow::new(header_cells);
123
124 let rows = vec![
125 TableRow::new(vec![
126 TableCell::new("12pt"),
127 TableCell::new("Arial"),
128 TableCell::new("Small Arial Text").font_size(12).font_family("Arial"),
129 ]),
130 TableRow::new(vec![
131 TableCell::new("18pt"),
132 TableCell::new("Calibri"),
133 TableCell::new("Medium Calibri Text").font_size(18).font_family("Calibri"),
134 ]),
135 TableRow::new(vec![
136 TableCell::new("24pt"),
137 TableCell::new("Times New Roman"),
138 TableCell::new("Large Times Text").font_size(24).font_family("Times New Roman"),
139 ]),
140 TableRow::new(vec![
141 TableCell::new("32pt"),
142 TableCell::new("Arial"),
143 TableCell::new("Extra Large Arial").font_size(32).font_family("Arial"),
144 ]),
145 ];
146
147 Table::new(
148 vec![vec![header_row], rows].concat(),
149 vec![2000000, 2500000, 3500000],
150 500000,
151 1500000,
152 )
153}
154
155fn create_combined_table() -> Table {
156 let header_cells = vec![
157 TableCell::new("Feature").bold().background_color("C0504D"),
158 TableCell::new("Styled Example").bold().background_color("C0504D"),
159 ];
160 let header_row = TableRow::new(header_cells);
161
162 let rows = vec![
163 TableRow::new(vec![
164 TableCell::new("Important Header"),
165 TableCell::new("Critical Data")
166 .bold()
167 .text_color("FFFFFF")
168 .background_color("C0504D")
169 .font_size(20),
170 ]),
171 TableRow::new(vec![
172 TableCell::new("Emphasis"),
173 TableCell::new("Highlighted Text")
174 .bold()
175 .italic()
176 .text_color("0000FF")
177 .font_size(18)
178 .font_family("Calibri"),
179 ]),
180 TableRow::new(vec![
181 TableCell::new("Warning"),
182 TableCell::new("Warning Message")
183 .bold()
184 .underline()
185 .text_color("FF6600")
186 .background_color("FFF4E6")
187 .font_size(16),
188 ]),
189 TableRow::new(vec![
190 TableCell::new("Success"),
191 TableCell::new("Success Indicator")
192 .bold()
193 .text_color("00AA00")
194 .background_color("E6F7E6")
195 .font_size(18)
196 .font_family("Arial"),
197 ]),
198 ];
199
200 Table::new(
201 vec![vec![header_row], rows].concat(),
202 vec![3000000, 5000000],
203 500000,
204 1500000,
205 )
206}Sourcepub fn align_left(self) -> Self
pub fn align_left(self) -> Self
Set horizontal text alignment to left
Examples found in repository?
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}Sourcepub fn align_right(self) -> Self
pub fn align_right(self) -> Self
Set horizontal text alignment to right
Examples found in repository?
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}Sourcepub fn align_center(self) -> Self
pub fn align_center(self) -> Self
Set horizontal text alignment to center
Examples found in repository?
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}Sourcepub fn valign(self, valign: CellVAlign) -> Self
pub fn valign(self, valign: CellVAlign) -> Self
Set vertical text alignment
Sourcepub fn valign_top(self) -> Self
pub fn valign_top(self) -> Self
Set vertical text alignment to top
Sourcepub fn valign_bottom(self) -> Self
pub fn valign_bottom(self) -> Self
Set vertical text alignment to bottom
Sourcepub fn with_row_span(self, span: u32) -> Self
pub fn with_row_span(self, span: u32) -> Self
Set row span (number of rows to merge down)
Sourcepub fn with_col_span(self, span: u32) -> Self
pub fn with_col_span(self, span: u32) -> Self
Set column span (number of columns to merge right)
Sourcepub fn with_v_merge(self) -> Self
pub fn with_v_merge(self) -> Self
Set vertical merge flag (for cells covered by row span)
Sourcepub fn with_h_merge(self) -> Self
pub fn with_h_merge(self) -> Self
Set horizontal merge flag (for cells covered by col span)
Sourcepub fn grid_span(self, span: u32) -> Self
pub fn grid_span(self, span: u32) -> Self
Set horizontal span (gridSpan) - this cell covers multiple columns
Examples found in repository?
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}Sourcepub fn row_span(self, span: u32) -> Self
pub fn row_span(self, span: u32) -> Self
Set vertical span (rowSpan) - this cell covers multiple rows
Examples found in repository?
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}Sourcepub fn h_merge(self) -> Self
pub fn h_merge(self) -> Self
Mark this cell as horizontally merged (covered by another cell’s gridSpan)
Examples found in repository?
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}Sourcepub fn v_merge(self) -> Self
pub fn v_merge(self) -> Self
Mark this cell as vertically merged (covered by another cell’s rowSpan)
Examples found in repository?
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}