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 grid_span: Option<u32>,
pub row_span: Option<u32>,
pub h_merge: bool,
pub v_merge: bool,
}Expand description
Table cell content with formatting options
Fields§
§text: StringCell text content
bold: boolBold text
italic: boolItalic text
underline: boolUnderlined text
text_color: Option<String>Text color (RGB hex, e.g., “FF0000”)
background_color: Option<String>Background color (RGB hex, e.g., “0000FF”)
font_size: Option<u32>Font size in points
font_family: Option<String>Font family name
align: CellAlignHorizontal text alignment
valign: CellVAlignVertical text alignment
wrap_text: boolEnable text wrapping
grid_span: Option<u32>Number of columns this cell spans (gridSpan attribute)
row_span: Option<u32>Number of rows this cell spans (rowSpan attribute)
h_merge: boolWhether this cell is horizontally merged (covered by a gridSpan)
v_merge: boolWhether this cell is vertically merged (covered by a rowSpan)
Implementations§
Source§impl TableCell
impl TableCell
Sourcepub fn new(text: &str) -> Self
pub fn new(text: &str) -> Self
Create a new table cell with text
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}69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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}69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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}69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}Sourcepub fn align_right(self) -> Self
pub fn align_right(self) -> Self
Set horizontal text alignment to right
Examples found in repository?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}Sourcepub fn align_center(self) -> Self
pub fn align_center(self) -> Self
Set horizontal text alignment to center
Examples found in repository?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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 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?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}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?
69fn main() -> Result<(), Box<dyn std::error::Error>> {
70 println!("╔══════════════════════════════════════════════════════════════╗");
71 println!("║ PPTX-RS Element Showcase - Complete Coverage ║");
72 println!("╚══════════════════════════════════════════════════════════════╝\n");
73
74 let mut slides = Vec::new();
75
76 // =========================================================================
77 // SLIDE 1: CenteredTitle Layout + Title Formatting
78 // =========================================================================
79 println!("📐 Slide 1: CenteredTitle Layout + Title Formatting");
80 slides.push(
81 SlideContent::new("PPTX-RS Element Showcase")
82 .layout(SlideLayout::CenteredTitle)
83 .title_size(54)
84 .title_bold(true)
85 .title_color("1F497D")
86 );
87
88 // =========================================================================
89 // SLIDE 2: TitleOnly Layout
90 // =========================================================================
91 println!("📐 Slide 2: TitleOnly Layout");
92 slides.push(
93 SlideContent::new("Section: Slide Layouts")
94 .layout(SlideLayout::TitleOnly)
95 .title_size(48)
96 .title_bold(true)
97 .title_color("C0504D")
98 );
99
100 // =========================================================================
101 // SLIDE 3: TitleAndContent Layout + All Text Formatting
102 // =========================================================================
103 println!("📝 Slide 3: TitleAndContent + Text Formatting");
104 slides.push(
105 SlideContent::new("Text Formatting Options")
106 .layout(SlideLayout::TitleAndContent)
107 .title_color("1F497D")
108 .title_bold(true)
109 .title_italic(true)
110 .title_underline(true)
111 .title_size(44)
112 .add_bullet("Normal text (default)")
113 .add_bullet("Bold content text")
114 .add_bullet("Italic content text")
115 .add_bullet("Underlined content")
116 .add_bullet("Custom font size (28pt)")
117 .add_bullet("Custom color (#4F81BD)")
118 .content_bold(true)
119 .content_italic(true)
120 .content_underline(true)
121 .content_size(28)
122 .content_color("4F81BD")
123 );
124
125 // =========================================================================
126 // SLIDE 4: TitleAndBigContent Layout
127 // =========================================================================
128 println!("📐 Slide 4: TitleAndBigContent Layout");
129 slides.push(
130 SlideContent::new("Key Highlights")
131 .layout(SlideLayout::TitleAndBigContent)
132 .title_color("1F497D")
133 .add_bullet("Large content area for emphasis")
134 .add_bullet("Perfect for key messages")
135 .add_bullet("Smaller title, bigger content")
136 .content_bold(true)
137 .content_size(32)
138 );
139
140 // =========================================================================
141 // SLIDE 5: TwoColumn Layout
142 // =========================================================================
143 println!("📐 Slide 5: TwoColumn Layout");
144 slides.push(
145 SlideContent::new("Two Column Comparison")
146 .layout(SlideLayout::TwoColumn)
147 .title_color("1F497D")
148 .add_bullet("Left Column Item 1")
149 .add_bullet("Left Column Item 2")
150 .add_bullet("Left Column Item 3")
151 .add_bullet("Right Column Item 1")
152 .add_bullet("Right Column Item 2")
153 .add_bullet("Right Column Item 3")
154 .content_size(24)
155 );
156
157 // =========================================================================
158 // SLIDE 6: Blank Layout
159 // =========================================================================
160 println!("📐 Slide 6: Blank Layout");
161 slides.push(
162 SlideContent::new("")
163 .layout(SlideLayout::Blank)
164 );
165
166 // =========================================================================
167 // SLIDE 7: Table with All Cell Styling Options
168 // =========================================================================
169 println!("📊 Slide 7: Table with Cell Styling");
170 let styled_table = TableBuilder::new(vec![1500000, 1500000, 1500000])
171 .add_row(TableRow::new(vec![
172 TableCell::new("Header 1").bold().background_color("1F497D"),
173 TableCell::new("Header 2").bold().background_color("4F81BD"),
174 TableCell::new("Header 3").bold().background_color("8064A2"),
175 ]))
176 .add_row(TableRow::new(vec![
177 TableCell::new("Bold Cell").bold(),
178 TableCell::new("Normal Cell"),
179 TableCell::new("Colored").background_color("9BBB59"),
180 ]))
181 .add_row(TableRow::new(vec![
182 TableCell::new("Red BG").background_color("C0504D"),
183 TableCell::new("Green BG").background_color("9BBB59"),
184 TableCell::new("Blue BG").background_color("4F81BD"),
185 ]))
186 .add_row(TableRow::new(vec![
187 TableCell::new("Row 3 Col 1"),
188 TableCell::new("Row 3 Col 2"),
189 TableCell::new("Row 3 Col 3").bold().background_color("F79646"),
190 ]))
191 .position(500000, 1800000)
192 .build();
193
194 slides.push(
195 SlideContent::new("Table with Cell Styling")
196 .table(styled_table)
197 .title_color("1F497D")
198 );
199
200 // =========================================================================
201 // SLIDE 8: Charts (Bar, Line, Pie)
202 // =========================================================================
203 println!("📈 Slide 8: Chart Types");
204
205 // Create chart data structures (for demonstration)
206 let _bar_chart = ChartBuilder::new("Sales by Region", ChartType::Bar)
207 .categories(vec!["North", "South", "East", "West"])
208 .add_series(ChartSeries::new("2023", vec![100.0, 80.0, 120.0, 90.0]))
209 .add_series(ChartSeries::new("2024", vec![120.0, 95.0, 140.0, 110.0]))
210 .build();
211
212 let _line_chart = ChartBuilder::new("Monthly Trend", ChartType::Line)
213 .categories(vec!["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
214 .add_series(ChartSeries::new("Revenue", vec![10.0, 12.0, 15.0, 14.0, 18.0, 22.0]))
215 .build();
216
217 let _pie_chart = ChartBuilder::new("Market Share", ChartType::Pie)
218 .categories(vec!["Product A", "Product B", "Product C", "Others"])
219 .add_series(ChartSeries::new("Share", vec![40.0, 30.0, 20.0, 10.0]))
220 .build();
221
222 slides.push(
223 SlideContent::new("Chart Types: Bar, Line, Pie")
224 .with_chart()
225 .title_color("1F497D")
226 .add_bullet("Bar Chart: Compare categories")
227 .add_bullet("Line Chart: Show trends over time")
228 .add_bullet("Pie Chart: Show proportions")
229 .content_size(24)
230 );
231
232 // =========================================================================
233 // SLIDE 9: Shapes with Different Fills
234 // =========================================================================
235 println!("🔷 Slide 9: Shapes with Fills");
236
237 let rect = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2000000, 1000000)
238 .with_fill(ShapeFill::new("4F81BD"))
239 .with_text("Rectangle");
240
241 let ellipse = Shape::new(ShapeType::Ellipse, 3000000, 1600000, 2000000, 1000000)
242 .with_fill(ShapeFill::new("9BBB59"))
243 .with_text("Ellipse");
244
245 let rounded = Shape::new(ShapeType::RoundedRectangle, 5500000, 1600000, 2000000, 1000000)
246 .with_fill(ShapeFill::new("C0504D"))
247 .with_text("Rounded");
248
249 let triangle = Shape::new(ShapeType::Triangle, 1500000, 3000000, 1500000, 1200000)
250 .with_fill(ShapeFill::new("8064A2"))
251 .with_text("Triangle");
252
253 let diamond = Shape::new(ShapeType::Diamond, 4000000, 3000000, 1500000, 1200000)
254 .with_fill(ShapeFill::new("F79646"))
255 .with_text("Diamond");
256
257 slides.push(
258 SlideContent::new("Shape Types with Color Fills")
259 .add_shape(rect)
260 .add_shape(ellipse)
261 .add_shape(rounded)
262 .add_shape(triangle)
263 .add_shape(diamond)
264 .title_color("1F497D")
265 );
266
267 // =========================================================================
268 // SLIDE 10: Gradient Fills (NEW)
269 // =========================================================================
270 println!("🌈 Slide 10: Gradient Fills");
271
272 // Horizontal gradient
273 let gradient_h = Shape::new(ShapeType::Rectangle, 500000, 1600000, 2500000, 1200000)
274 .with_gradient(GradientFill::linear("1565C0", "42A5F5", GradientDirection::Horizontal))
275 .with_text("Horizontal");
276
277 // Vertical gradient
278 let gradient_v = Shape::new(ShapeType::Rectangle, 3200000, 1600000, 2500000, 1200000)
279 .with_gradient(GradientFill::linear("2E7D32", "81C784", GradientDirection::Vertical))
280 .with_text("Vertical");
281
282 // Diagonal gradient
283 let gradient_d = Shape::new(ShapeType::RoundedRectangle, 5900000, 1600000, 2500000, 1200000)
284 .with_gradient(GradientFill::linear("C62828", "EF9A9A", GradientDirection::DiagonalDown))
285 .with_text("Diagonal");
286
287 // Three-color gradient
288 let gradient_3 = Shape::new(ShapeType::Ellipse, 1800000, 3200000, 2500000, 1200000)
289 .with_gradient(GradientFill::three_color("FF6F00", "FFC107", "FFEB3B", GradientDirection::Horizontal))
290 .with_text("3-Color");
291
292 // Custom angle gradient
293 let gradient_angle = Shape::new(ShapeType::RoundedRectangle, 4800000, 3200000, 2500000, 1200000)
294 .with_gradient(GradientFill::linear("7B1FA2", "E1BEE7", GradientDirection::Angle(135)))
295 .with_text("135° Angle");
296
297 slides.push(
298 SlideContent::new("Gradient Fills - Multiple Directions")
299 .add_shape(gradient_h)
300 .add_shape(gradient_v)
301 .add_shape(gradient_d)
302 .add_shape(gradient_3)
303 .add_shape(gradient_angle)
304 .title_color("1F497D")
305 );
306
307 // =========================================================================
308 // SLIDE 11: Transparency (NEW)
309 // =========================================================================
310 println!("👻 Slide 11: Transparency Effects");
311
312 // Base shape (fully opaque)
313 let base = Shape::new(ShapeType::Rectangle, 1000000, 1800000, 3000000, 2000000)
314 .with_fill(ShapeFill::new("1565C0"))
315 .with_text("Base (100%)");
316
317 // 25% transparent overlay
318 let trans_25 = Shape::new(ShapeType::Rectangle, 2000000, 2200000, 2500000, 1500000)
319 .with_fill(ShapeFill::new("F44336").with_transparency(25))
320 .with_line(ShapeLine::new("B71C1C", 25400))
321 .with_text("25% Transparent");
322
323 // 50% transparent overlay
324 let trans_50 = Shape::new(ShapeType::Ellipse, 4500000, 1800000, 2500000, 2000000)
325 .with_fill(ShapeFill::new("4CAF50").with_transparency(50))
326 .with_line(ShapeLine::new("1B5E20", 25400))
327 .with_text("50% Transparent");
328
329 // 75% transparent overlay
330 let trans_75 = Shape::new(ShapeType::RoundedRectangle, 5500000, 2500000, 2500000, 1500000)
331 .with_fill(ShapeFill::new("FF9800").with_transparency(75))
332 .with_line(ShapeLine::new("E65100", 25400))
333 .with_text("75% Transparent");
334
335 slides.push(
336 SlideContent::new("Transparency Effects - Overlapping Shapes")
337 .add_shape(base)
338 .add_shape(trans_25)
339 .add_shape(trans_50)
340 .add_shape(trans_75)
341 .title_color("1F497D")
342 );
343
344 // =========================================================================
345 // SLIDE 12: Styled Connectors (NEW)
346 // =========================================================================
347 println!("🔗 Slide 12: Styled Connectors");
348
349 // Create shapes to connect
350 let box1 = Shape::new(ShapeType::RoundedRectangle, 500000, 1800000, 1800000, 800000)
351 .with_id(100)
352 .with_fill(ShapeFill::new("1565C0"))
353 .with_text("Start");
354
355 let box2 = Shape::new(ShapeType::RoundedRectangle, 3500000, 1800000, 1800000, 800000)
356 .with_id(101)
357 .with_fill(ShapeFill::new("2E7D32"))
358 .with_text("Process");
359
360 let box3 = Shape::new(ShapeType::RoundedRectangle, 6500000, 1800000, 1800000, 800000)
361 .with_id(102)
362 .with_fill(ShapeFill::new("C62828"))
363 .with_text("End");
364
365 // Straight connector with arrow
366 let conn1 = Connector::straight(2300000, 2200000, 3500000, 2200000)
367 .with_line(ConnectorLine::new("1565C0", 25400))
368 .with_end_arrow(ArrowType::Triangle)
369 .with_arrow_size(ArrowSize::Large);
370
371 // Elbow connector with stealth arrow
372 let conn2 = Connector::elbow(5300000, 2200000, 6500000, 2200000)
373 .with_line(ConnectorLine::new("2E7D32", 38100).with_dash(LineDash::Dash))
374 .with_end_arrow(ArrowType::Stealth)
375 .with_arrow_size(ArrowSize::Medium);
376
377 // Curved connector examples
378 let box4 = Shape::new(ShapeType::Ellipse, 1000000, 3200000, 1500000, 800000)
379 .with_id(103)
380 .with_fill(ShapeFill::new("7B1FA2"))
381 .with_text("A");
382
383 let box5 = Shape::new(ShapeType::Ellipse, 4000000, 3200000, 1500000, 800000)
384 .with_id(104)
385 .with_fill(ShapeFill::new("00838F"))
386 .with_text("B");
387
388 let box6 = Shape::new(ShapeType::Ellipse, 7000000, 3200000, 1500000, 800000)
389 .with_id(105)
390 .with_fill(ShapeFill::new("EF6C00"))
391 .with_text("C");
392
393 // Curved connector with diamond arrow
394 let conn3 = Connector::curved(2500000, 3600000, 4000000, 3600000)
395 .with_line(ConnectorLine::new("7B1FA2", 19050).with_dash(LineDash::DashDot))
396 .with_arrows(ArrowType::Oval, ArrowType::Diamond);
397
398 // Dotted connector
399 let conn4 = Connector::straight(5500000, 3600000, 7000000, 3600000)
400 .with_line(ConnectorLine::new("00838F", 12700).with_dash(LineDash::Dot))
401 .with_end_arrow(ArrowType::Open);
402
403 slides.push(
404 SlideContent::new("Styled Connectors - Types, Arrows, Dashes")
405 .add_shape(box1)
406 .add_shape(box2)
407 .add_shape(box3)
408 .add_shape(box4)
409 .add_shape(box5)
410 .add_shape(box6)
411 .add_connector(conn1)
412 .add_connector(conn2)
413 .add_connector(conn3)
414 .add_connector(conn4)
415 .title_color("1F497D")
416 );
417
418 // =========================================================================
419 // SLIDE 13: Images
420 // =========================================================================
421 println!("🖼️ Slide 13: Image Placeholders");
422
423 let img1 = Image::new("logo.png", 2500000, 1800000, "png")
424 .position(500000, 1600000);
425 let img2 = Image::new("photo.jpg", 2500000, 1800000, "jpg")
426 .position(3500000, 1600000);
427 let img3 = Image::new("diagram.png", 2000000, 1800000, "png")
428 .position(6500000, 1600000);
429
430 slides.push(
431 SlideContent::new("Image Placeholders")
432 .add_image(img1)
433 .add_image(img2)
434 .add_image(img3)
435 .title_color("1F497D")
436 );
437
438 // =========================================================================
439 // SLIDE 11: Advanced Table with Borders & Alignment (NEW)
440 // =========================================================================
441 println!("📊 Slide 11: Advanced Table (borders, alignment, merged cells)");
442
443 // Build advanced table using generator's TableBuilder with alignment
444 let advanced_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
445 .add_row(TableRow::new(vec![
446 TableCell::new("Q1 2024 Financial Report").bold().background_color("1F4E79").text_color("FFFFFF").align_center().font_size(14),
447 TableCell::new("").background_color("1F4E79"),
448 TableCell::new("").background_color("1F4E79"),
449 TableCell::new("").background_color("1F4E79"),
450 ]))
451 .add_row(TableRow::new(vec![
452 TableCell::new("Category").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
453 TableCell::new("Revenue").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
454 TableCell::new("Expenses").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
455 TableCell::new("Profit").bold().background_color("2E75B6").text_color("FFFFFF").align_center(),
456 ]))
457 .add_row(TableRow::new(vec![
458 TableCell::new("Product Sales").text_color("000000").align_left(),
459 TableCell::new("$1,250,000").text_color("2E7D32").align_right(),
460 TableCell::new("$450,000").text_color("C62828").align_right(),
461 TableCell::new("$800,000").bold().text_color("2E7D32").align_right(),
462 ]))
463 .add_row(TableRow::new(vec![
464 TableCell::new("Services").text_color("000000").align_left(),
465 TableCell::new("$890,000").text_color("2E7D32").align_right(),
466 TableCell::new("$320,000").text_color("C62828").align_right(),
467 TableCell::new("$570,000").bold().text_color("2E7D32").align_right(),
468 ]))
469 .add_row(TableRow::new(vec![
470 TableCell::new("Total").bold().background_color("E7E6E6").text_color("000000").align_left(),
471 TableCell::new("$2,140,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
472 TableCell::new("$770,000").bold().background_color("E7E6E6").text_color("000000").align_right(),
473 TableCell::new("$1,370,000").bold().background_color("C6EFCE").text_color("006100").align_right(),
474 ]))
475 .position(300000, 1600000)
476 .build();
477
478 slides.push(
479 SlideContent::new("Financial Report - Advanced Table")
480 .table(advanced_table)
481 .title_color("1F4E79")
482 .title_bold(true)
483 );
484
485 // =========================================================================
486 // SLIDE 12: Comparison Matrix Table (NEW)
487 // =========================================================================
488 println!("📊 Slide 12: Comparison Matrix Table");
489
490 let comparison_table = TableBuilder::new(vec![2000000, 1500000, 1500000, 1500000])
491 .add_row(TableRow::new(vec![
492 TableCell::new("Feature").bold().background_color("4472C4").text_color("FFFFFF"),
493 TableCell::new("Basic").bold().background_color("4472C4").text_color("FFFFFF"),
494 TableCell::new("Pro").bold().background_color("4472C4").text_color("FFFFFF"),
495 TableCell::new("Enterprise").bold().background_color("4472C4").text_color("FFFFFF"),
496 ]))
497 .add_row(TableRow::new(vec![
498 TableCell::new("Storage").text_color("000000"),
499 TableCell::new("5 GB").text_color("000000"),
500 TableCell::new("50 GB").text_color("000000"),
501 TableCell::new("Unlimited").bold().text_color("2E7D32"),
502 ]))
503 .add_row(TableRow::new(vec![
504 TableCell::new("Users").text_color("000000"),
505 TableCell::new("1").text_color("000000"),
506 TableCell::new("10").text_color("000000"),
507 TableCell::new("Unlimited").bold().text_color("2E7D32"),
508 ]))
509 .add_row(TableRow::new(vec![
510 TableCell::new("Support").text_color("000000"),
511 TableCell::new("Email").text_color("000000"),
512 TableCell::new("24/7 Chat").text_color("000000"),
513 TableCell::new("Dedicated").bold().text_color("2E7D32"),
514 ]))
515 .add_row(TableRow::new(vec![
516 TableCell::new("API Access").text_color("000000"),
517 TableCell::new("No").text_color("C62828"),
518 TableCell::new("Yes").text_color("2E7D32"),
519 TableCell::new("Yes + Priority").bold().text_color("2E7D32"),
520 ]))
521 .add_row(TableRow::new(vec![
522 TableCell::new("Price/month").bold().background_color("F2F2F2").text_color("000000"),
523 TableCell::new("$9").bold().background_color("F2F2F2").text_color("000000"),
524 TableCell::new("$29").bold().background_color("F2F2F2").text_color("000000"),
525 TableCell::new("$99").bold().background_color("F2F2F2").text_color("000000"),
526 ]))
527 .position(500000, 1600000)
528 .build();
529
530 slides.push(
531 SlideContent::new("Pricing Comparison Matrix")
532 .table(comparison_table)
533 .title_color("4472C4")
534 .title_bold(true)
535 );
536
537 // =========================================================================
538 // SLIDE 13: Process Flow with Shapes (NEW - SmartArt-like)
539 // =========================================================================
540 println!("🔷 Slide 13: Process Flow (SmartArt-style)");
541
542 // Create process flow using shapes
543 let step1 = Shape::new(ShapeType::RoundedRectangle, 300000, 2000000, 1400000, 800000)
544 .with_fill(ShapeFill::new("4472C4"))
545 .with_text("1. Research");
546 let arrow1 = Shape::new(ShapeType::RightArrow, 1800000, 2200000, 400000, 400000)
547 .with_fill(ShapeFill::new("A5A5A5"));
548 let step2 = Shape::new(ShapeType::RoundedRectangle, 2300000, 2000000, 1400000, 800000)
549 .with_fill(ShapeFill::new("ED7D31"))
550 .with_text("2. Design");
551 let arrow2 = Shape::new(ShapeType::RightArrow, 3800000, 2200000, 400000, 400000)
552 .with_fill(ShapeFill::new("A5A5A5"));
553 let step3 = Shape::new(ShapeType::RoundedRectangle, 4300000, 2000000, 1400000, 800000)
554 .with_fill(ShapeFill::new("70AD47"))
555 .with_text("3. Develop");
556 let arrow3 = Shape::new(ShapeType::RightArrow, 5800000, 2200000, 400000, 400000)
557 .with_fill(ShapeFill::new("A5A5A5"));
558 let step4 = Shape::new(ShapeType::RoundedRectangle, 6300000, 2000000, 1400000, 800000)
559 .with_fill(ShapeFill::new("5B9BD5"))
560 .with_text("4. Deploy");
561
562 slides.push(
563 SlideContent::new("Development Process Flow")
564 .add_shape(step1)
565 .add_shape(arrow1)
566 .add_shape(step2)
567 .add_shape(arrow2)
568 .add_shape(step3)
569 .add_shape(arrow3)
570 .add_shape(step4)
571 .title_color("1F497D")
572 .title_bold(true)
573 );
574
575 // =========================================================================
576 // SLIDE 14: Organization Chart with Shapes (NEW)
577 // =========================================================================
578 println!("🔷 Slide 14: Organization Chart");
579
580 // CEO at top
581 let ceo = Shape::new(ShapeType::RoundedRectangle, 3500000, 1400000, 2000000, 600000)
582 .with_fill(ShapeFill::new("1F4E79"))
583 .with_text("CEO");
584
585 // Vertical line from CEO
586 let line1 = Shape::new(ShapeType::Rectangle, 4450000, 2000000, 100000, 400000)
587 .with_fill(ShapeFill::new("A5A5A5"));
588
589 // Horizontal connector
590 let hline = Shape::new(ShapeType::Rectangle, 1950000, 2400000, 5100000, 50000)
591 .with_fill(ShapeFill::new("A5A5A5"));
592
593 // CTO, CFO, COO
594 let cto = Shape::new(ShapeType::RoundedRectangle, 1000000, 2600000, 1800000, 500000)
595 .with_fill(ShapeFill::new("2E75B6"))
596 .with_text("CTO");
597 let cfo = Shape::new(ShapeType::RoundedRectangle, 3600000, 2600000, 1800000, 500000)
598 .with_fill(ShapeFill::new("2E75B6"))
599 .with_text("CFO");
600 let coo = Shape::new(ShapeType::RoundedRectangle, 6200000, 2600000, 1800000, 500000)
601 .with_fill(ShapeFill::new("2E75B6"))
602 .with_text("COO");
603
604 // Vertical lines to departments
605 let vline1 = Shape::new(ShapeType::Rectangle, 1850000, 2450000, 50000, 150000)
606 .with_fill(ShapeFill::new("A5A5A5"));
607 let vline2 = Shape::new(ShapeType::Rectangle, 4450000, 2450000, 50000, 150000)
608 .with_fill(ShapeFill::new("A5A5A5"));
609 let vline3 = Shape::new(ShapeType::Rectangle, 7050000, 2450000, 50000, 150000)
610 .with_fill(ShapeFill::new("A5A5A5"));
611
612 // Teams under CTO
613 let eng = Shape::new(ShapeType::Rectangle, 500000, 3300000, 1200000, 400000)
614 .with_fill(ShapeFill::new("BDD7EE"))
615 .with_text("Engineering");
616 let product = Shape::new(ShapeType::Rectangle, 1800000, 3300000, 1200000, 400000)
617 .with_fill(ShapeFill::new("BDD7EE"))
618 .with_text("Product");
619
620 slides.push(
621 SlideContent::new("Organization Structure")
622 .add_shape(ceo)
623 .add_shape(line1)
624 .add_shape(hline)
625 .add_shape(cto)
626 .add_shape(cfo)
627 .add_shape(coo)
628 .add_shape(vline1)
629 .add_shape(vline2)
630 .add_shape(vline3)
631 .add_shape(eng)
632 .add_shape(product)
633 .title_color("1F4E79")
634 .title_bold(true)
635 );
636
637 // =========================================================================
638 // SLIDE 15: PDCA Cycle Diagram (NEW)
639 // =========================================================================
640 println!("🔷 Slide 15: PDCA Cycle Diagram");
641
642 // Four quadrants for PDCA
643 let plan = Shape::new(ShapeType::RoundedRectangle, 1500000, 1600000, 2500000, 1500000)
644 .with_fill(ShapeFill::new("4472C4"))
645 .with_text("PLAN\n\nDefine goals\nand strategy");
646 let do_box = Shape::new(ShapeType::RoundedRectangle, 4500000, 1600000, 2500000, 1500000)
647 .with_fill(ShapeFill::new("ED7D31"))
648 .with_text("DO\n\nImplement\nthe plan");
649 let check = Shape::new(ShapeType::RoundedRectangle, 4500000, 3300000, 2500000, 1500000)
650 .with_fill(ShapeFill::new("70AD47"))
651 .with_text("CHECK\n\nMeasure\nresults");
652 let act = Shape::new(ShapeType::RoundedRectangle, 1500000, 3300000, 2500000, 1500000)
653 .with_fill(ShapeFill::new("FFC000"))
654 .with_text("ACT\n\nAdjust and\nimprove");
655
656 // Arrows between quadrants
657 let arr1 = Shape::new(ShapeType::RightArrow, 4100000, 2100000, 300000, 300000)
658 .with_fill(ShapeFill::new("A5A5A5"));
659 let arr2 = Shape::new(ShapeType::DownArrow, 5600000, 3200000, 300000, 200000)
660 .with_fill(ShapeFill::new("A5A5A5"));
661 let arr3 = Shape::new(ShapeType::LeftArrow, 4100000, 3800000, 300000, 300000)
662 .with_fill(ShapeFill::new("A5A5A5"));
663 let arr4 = Shape::new(ShapeType::UpArrow, 2600000, 3200000, 300000, 200000)
664 .with_fill(ShapeFill::new("A5A5A5"));
665
666 slides.push(
667 SlideContent::new("PDCA Continuous Improvement Cycle")
668 .add_shape(plan)
669 .add_shape(do_box)
670 .add_shape(check)
671 .add_shape(act)
672 .add_shape(arr1)
673 .add_shape(arr2)
674 .add_shape(arr3)
675 .add_shape(arr4)
676 .title_color("1F497D")
677 .title_bold(true)
678 );
679
680 // =========================================================================
681 // SLIDE 16: Pyramid Diagram (Maslow's Hierarchy) (NEW)
682 // =========================================================================
683 println!("🔷 Slide 16: Pyramid Diagram");
684
685 // Build pyramid from bottom to top
686 let level5 = Shape::new(ShapeType::Trapezoid, 500000, 4000000, 8000000, 600000)
687 .with_fill(ShapeFill::new("C00000"))
688 .with_text("Physiological Needs - Food, Water, Shelter");
689 let level4 = Shape::new(ShapeType::Trapezoid, 1000000, 3400000, 7000000, 600000)
690 .with_fill(ShapeFill::new("ED7D31"))
691 .with_text("Safety Needs - Security, Stability");
692 let level3 = Shape::new(ShapeType::Trapezoid, 1500000, 2800000, 6000000, 600000)
693 .with_fill(ShapeFill::new("FFC000"))
694 .with_text("Love & Belonging - Relationships");
695 let level2 = Shape::new(ShapeType::Trapezoid, 2000000, 2200000, 5000000, 600000)
696 .with_fill(ShapeFill::new("70AD47"))
697 .with_text("Esteem - Achievement, Respect");
698 let level1 = Shape::new(ShapeType::Triangle, 2500000, 1500000, 4000000, 700000)
699 .with_fill(ShapeFill::new("4472C4"))
700 .with_text("Self-Actualization");
701
702 slides.push(
703 SlideContent::new("Maslow's Hierarchy of Needs")
704 .add_shape(level5)
705 .add_shape(level4)
706 .add_shape(level3)
707 .add_shape(level2)
708 .add_shape(level1)
709 .title_color("1F497D")
710 .title_bold(true)
711 );
712
713 // =========================================================================
714 // SLIDE 17: Venn Diagram (NEW)
715 // =========================================================================
716 println!("🔷 Slide 17: Venn Diagram");
717
718 // Three overlapping circles
719 let circle1 = Shape::new(ShapeType::Ellipse, 1500000, 1800000, 3000000, 3000000)
720 .with_fill(ShapeFill::new("4472C4"))
721 .with_text("Skills");
722 let circle2 = Shape::new(ShapeType::Ellipse, 3500000, 1800000, 3000000, 3000000)
723 .with_fill(ShapeFill::new("ED7D31"))
724 .with_text("Passion");
725 let circle3 = Shape::new(ShapeType::Ellipse, 2500000, 3200000, 3000000, 3000000)
726 .with_fill(ShapeFill::new("70AD47"))
727 .with_text("Market Need");
728
729 // Center label
730 let center = Shape::new(ShapeType::Ellipse, 3200000, 2800000, 1600000, 800000)
731 .with_fill(ShapeFill::new("FFFFFF"))
732 .with_text("IKIGAI");
733
734 slides.push(
735 SlideContent::new("Finding Your Ikigai - Venn Diagram")
736 .add_shape(circle1)
737 .add_shape(circle2)
738 .add_shape(circle3)
739 .add_shape(center)
740 .title_color("1F497D")
741 .title_bold(true)
742 );
743
744 // =========================================================================
745 // SLIDE 18: Timeline/Roadmap (NEW)
746 // =========================================================================
747 println!("📊 Slide 18: Project Timeline");
748
749 let timeline_table = TableBuilder::new(vec![1500000, 1500000, 1500000, 1500000, 1500000])
750 .add_row(TableRow::new(vec![
751 TableCell::new("Q1 2024").bold().background_color("4472C4").text_color("FFFFFF"),
752 TableCell::new("Q2 2024").bold().background_color("4472C4").text_color("FFFFFF"),
753 TableCell::new("Q3 2024").bold().background_color("4472C4").text_color("FFFFFF"),
754 TableCell::new("Q4 2024").bold().background_color("4472C4").text_color("FFFFFF"),
755 TableCell::new("Q1 2025").bold().background_color("4472C4").text_color("FFFFFF"),
756 ]))
757 .add_row(TableRow::new(vec![
758 TableCell::new("Research\n& Planning").background_color("BDD7EE").text_color("1F497D"),
759 TableCell::new("Design\nPhase").background_color("BDD7EE").text_color("1F497D"),
760 TableCell::new("Development\nSprint 1-3").background_color("C6EFCE").text_color("006100"),
761 TableCell::new("Testing\n& QA").background_color("FCE4D6").text_color("C65911"),
762 TableCell::new("Launch\n& Support").background_color("E2EFDA").text_color("375623"),
763 ]))
764 .add_row(TableRow::new(vec![
765 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
766 TableCell::new("✓ Complete").bold().text_color("2E7D32"),
767 TableCell::new("In Progress").text_color("ED7D31"),
768 TableCell::new("Planned").text_color("7F7F7F"),
769 TableCell::new("Planned").text_color("7F7F7F"),
770 ]))
771 .position(300000, 2000000)
772 .build();
773
774 slides.push(
775 SlideContent::new("Project Roadmap 2024-2025")
776 .table(timeline_table)
777 .title_color("1F497D")
778 .title_bold(true)
779 );
780
781 // =========================================================================
782 // SLIDE 19: Dashboard Summary (NEW - using Dimension API)
783 // =========================================================================
784 println!("🔷 Slide 19: Dashboard with KPIs (Dimension API)");
785
786 // KPI boxes using ratio-based positioning — automatically adapts to any slide size
787 let kpi1 = Shape::from_dimensions(ShapeType::RoundedRectangle,
788 Dimension::percent(3.0), Dimension::percent(23.0),
789 Dimension::percent(22.0), Dimension::percent(18.0),
790 ).with_fill(ShapeFill::new("4472C4")).with_text("Revenue\n\n$2.14M\n+15% YoY");
791
792 let kpi2 = Shape::from_dimensions(ShapeType::RoundedRectangle,
793 Dimension::percent(27.0), Dimension::percent(23.0),
794 Dimension::percent(22.0), Dimension::percent(18.0),
795 ).with_fill(ShapeFill::new("70AD47")).with_text("Customers\n\n12,450\n+22% YoY");
796
797 let kpi3 = Shape::from_dimensions(ShapeType::RoundedRectangle,
798 Dimension::percent(51.0), Dimension::percent(23.0),
799 Dimension::percent(22.0), Dimension::percent(18.0),
800 ).with_fill(ShapeFill::new("ED7D31")).with_text("NPS Score\n\n72\n+8 pts");
801
802 let kpi4 = Shape::from_dimensions(ShapeType::RoundedRectangle,
803 Dimension::percent(75.0), Dimension::percent(23.0),
804 Dimension::percent(22.0), Dimension::percent(18.0),
805 ).with_fill(ShapeFill::new("5B9BD5")).with_text("Retention\n\n94%\n+3% YoY");
806
807 // Status indicators using mixed units: percent for X, inches for size
808 let status1 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
809 .at(Dimension::percent(14.0), Dimension::percent(42.0))
810 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
811 .with_fill(ShapeFill::new("70AD47"));
812 let status2 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
813 .at(Dimension::percent(38.0), Dimension::percent(42.0))
814 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
815 .with_fill(ShapeFill::new("70AD47"));
816 let status3 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
817 .at(Dimension::percent(62.0), Dimension::percent(42.0))
818 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
819 .with_fill(ShapeFill::new("FFC000"));
820 let status4 = Shape::new(ShapeType::Ellipse, 0, 0, 0, 0)
821 .at(Dimension::percent(86.0), Dimension::percent(42.0))
822 .with_dimensions(Dimension::Inches(0.3), Dimension::Inches(0.3))
823 .with_fill(ShapeFill::new("70AD47"));
824
825 slides.push(
826 SlideContent::new("Executive Dashboard - Q1 2024")
827 .add_shape(kpi1)
828 .add_shape(kpi2)
829 .add_shape(kpi3)
830 .add_shape(kpi4)
831 .add_shape(status1)
832 .add_shape(status2)
833 .add_shape(status3)
834 .add_shape(status4)
835 .title_color("1F497D")
836 .title_bold(true)
837 );
838
839 // =========================================================================
840 // SLIDE 20: Summary Slide (NEW)
841 // =========================================================================
842 println!("📝 Slide 20: Summary with Speaker Notes");
843
844 slides.push(
845 SlideContent::new("Summary & Next Steps")
846 .layout(SlideLayout::TitleAndContent)
847 .title_color("1F497D")
848 .title_bold(true)
849 .add_bullet("Completed: Research, Design, Initial Development")
850 .add_bullet("In Progress: Sprint 3 Development")
851 .add_bullet("Next: QA Testing Phase (Q4 2024)")
852 .add_bullet("Launch Target: Q1 2025")
853 .add_bullet("Key Risks: Resource constraints, Timeline pressure")
854 .content_size(24)
855 .notes("Speaker Notes:\n\n1. Emphasize the progress made\n2. Highlight key achievements\n3. Address any concerns about timeline\n4. Open for Q&A")
856 );
857
858 // =========================================================================
859 // SLIDE 21: Bullet Styles (NEW v0.2.1)
860 // =========================================================================
861 println!("🔢 Slide 21: Bullet Styles (NEW)");
862
863 // Numbered list
864 slides.push(
865 SlideContent::new("Bullet Styles - Numbered List")
866 .layout(SlideLayout::TitleAndContent)
867 .title_color("1F497D")
868 .title_bold(true)
869 .with_bullet_style(BulletStyle::Number)
870 .add_bullet("First numbered item")
871 .add_bullet("Second numbered item")
872 .add_bullet("Third numbered item")
873 .add_bullet("Fourth numbered item")
874 .content_size(28)
875 );
876
877 // =========================================================================
878 // SLIDE 22: Lettered Lists (NEW v0.2.1)
879 // =========================================================================
880 println!("🔤 Slide 22: Lettered Lists (NEW)");
881
882 slides.push(
883 SlideContent::new("Bullet Styles - Lettered Lists")
884 .layout(SlideLayout::TitleAndContent)
885 .title_color("1F497D")
886 .title_bold(true)
887 .add_lettered("Option A - First choice")
888 .add_lettered("Option B - Second choice")
889 .add_lettered("Option C - Third choice")
890 .add_lettered("Option D - Fourth choice")
891 .content_size(28)
892 );
893
894 // =========================================================================
895 // SLIDE 23: Roman Numerals (NEW v0.2.1)
896 // =========================================================================
897 println!("🏛️ Slide 23: Roman Numerals (NEW)");
898
899 slides.push(
900 SlideContent::new("Bullet Styles - Roman Numerals")
901 .layout(SlideLayout::TitleAndContent)
902 .title_color("1F497D")
903 .title_bold(true)
904 .with_bullet_style(BulletStyle::RomanUpper)
905 .add_bullet("Chapter I - Introduction")
906 .add_bullet("Chapter II - Background")
907 .add_bullet("Chapter III - Methodology")
908 .add_bullet("Chapter IV - Results")
909 .add_bullet("Chapter V - Conclusion")
910 .content_size(28)
911 );
912
913 // =========================================================================
914 // SLIDE 24: Custom Bullets (NEW v0.2.1)
915 // =========================================================================
916 println!("⭐ Slide 24: Custom Bullets (NEW)");
917
918 slides.push(
919 SlideContent::new("Bullet Styles - Custom Characters")
920 .layout(SlideLayout::TitleAndContent)
921 .title_color("1F497D")
922 .title_bold(true)
923 .add_styled_bullet("Star bullet point", BulletStyle::Custom('★'))
924 .add_styled_bullet("Arrow bullet point", BulletStyle::Custom('→'))
925 .add_styled_bullet("Check bullet point", BulletStyle::Custom('✓'))
926 .add_styled_bullet("Diamond bullet point", BulletStyle::Custom('◆'))
927 .add_styled_bullet("Heart bullet point", BulletStyle::Custom('♥'))
928 .content_size(28)
929 );
930
931 // =========================================================================
932 // SLIDE 25: Sub-bullets / Hierarchy (NEW v0.2.1)
933 // =========================================================================
934 println!("📊 Slide 25: Sub-bullets Hierarchy (NEW)");
935
936 slides.push(
937 SlideContent::new("Bullet Styles - Hierarchical Lists")
938 .layout(SlideLayout::TitleAndContent)
939 .title_color("1F497D")
940 .title_bold(true)
941 .add_bullet("Main Topic 1")
942 .add_sub_bullet("Supporting detail A")
943 .add_sub_bullet("Supporting detail B")
944 .add_bullet("Main Topic 2")
945 .add_sub_bullet("Supporting detail C")
946 .add_sub_bullet("Supporting detail D")
947 .add_bullet("Main Topic 3")
948 .content_size(24)
949 );
950
951 // =========================================================================
952 // SLIDE 26: Text Enhancements (NEW v0.2.1)
953 // =========================================================================
954 println!("✏️ Slide 26: Text Enhancements (NEW)");
955
956 // Use BulletPoint with formatting
957 let strikethrough_bullet = BulletPoint::new("Strikethrough: This text is crossed out").strikethrough();
958 let highlight_bullet = BulletPoint::new("Highlight: Yellow background for emphasis").highlight("FFFF00");
959 let subscript_bullet = BulletPoint::new("Subscript: H₂O - for chemical formulas").subscript();
960 let superscript_bullet = BulletPoint::new("Superscript: x² - for math expressions").superscript();
961 let bold_colored = BulletPoint::new("Combined: Bold + Red color").bold().color("FF0000");
962
963 let mut text_enhancements_slide = SlideContent::new("Text Enhancements - New Formatting")
964 .layout(SlideLayout::TitleAndContent)
965 .title_color("1F497D")
966 .title_bold(true)
967 .content_size(24);
968 text_enhancements_slide.bullets.push(strikethrough_bullet);
969 text_enhancements_slide.bullets.push(highlight_bullet);
970 text_enhancements_slide.bullets.push(subscript_bullet);
971 text_enhancements_slide.bullets.push(superscript_bullet);
972 text_enhancements_slide.bullets.push(bold_colored);
973
974 slides.push(text_enhancements_slide);
975
976 // =========================================================================
977 // SLIDE 27: Font Size Presets (NEW v0.2.1)
978 // =========================================================================
979 println!("🔤 Slide 27: Font Size Presets (NEW)");
980
981 // Demonstrate different font sizes per bullet
982 let large_bullet = BulletPoint::new(&format!("LARGE: {}pt - Extra large text", font_sizes::LARGE)).font_size(font_sizes::LARGE);
983 let heading_bullet = BulletPoint::new(&format!("HEADING: {}pt - Section headers", font_sizes::HEADING)).font_size(font_sizes::HEADING);
984 let body_bullet = BulletPoint::new(&format!("BODY: {}pt - Regular content", font_sizes::BODY)).font_size(font_sizes::BODY);
985 let small_bullet = BulletPoint::new(&format!("SMALL: {}pt - Smaller text", font_sizes::SMALL)).font_size(font_sizes::SMALL);
986 let caption_bullet = BulletPoint::new(&format!("CAPTION: {}pt - Captions and notes", font_sizes::CAPTION)).font_size(font_sizes::CAPTION);
987
988 let mut font_size_slide = SlideContent::new("Font Size Presets - Each line different size")
989 .layout(SlideLayout::TitleAndContent)
990 .title_color("1F497D")
991 .title_bold(true)
992 .title_size(font_sizes::TITLE);
993 font_size_slide.bullets.push(large_bullet);
994 font_size_slide.bullets.push(heading_bullet);
995 font_size_slide.bullets.push(body_bullet);
996 font_size_slide.bullets.push(small_bullet);
997 font_size_slide.bullets.push(caption_bullet);
998
999 slides.push(font_size_slide);
1000
1001 // =========================================================================
1002 // SLIDE 28: Theme Colors (NEW v0.2.1)
1003 // =========================================================================
1004 println!("🎨 Slide 28: Theme Colors (NEW)");
1005
1006 // Create shapes with theme colors
1007 let corporate_shape = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1800000, 800000)
1008 .with_fill(ShapeFill::new(themes::CORPORATE.primary))
1009 .with_text("Corporate");
1010
1011 let modern_shape = Shape::new(ShapeType::Rectangle, 2500000, 1600000, 1800000, 800000)
1012 .with_fill(ShapeFill::new(themes::MODERN.primary))
1013 .with_text("Modern");
1014
1015 let vibrant_shape = Shape::new(ShapeType::Rectangle, 4500000, 1600000, 1800000, 800000)
1016 .with_fill(ShapeFill::new(themes::VIBRANT.primary))
1017 .with_text("Vibrant");
1018
1019 let dark_shape = Shape::new(ShapeType::Rectangle, 6500000, 1600000, 1800000, 800000)
1020 .with_fill(ShapeFill::new(themes::DARK.primary))
1021 .with_text("Dark");
1022
1023 let nature_shape = Shape::new(ShapeType::Rectangle, 500000, 2700000, 1800000, 800000)
1024 .with_fill(ShapeFill::new(themes::NATURE.primary))
1025 .with_text("Nature");
1026
1027 let tech_shape = Shape::new(ShapeType::Rectangle, 2500000, 2700000, 1800000, 800000)
1028 .with_fill(ShapeFill::new(themes::TECH.primary))
1029 .with_text("Tech");
1030
1031 let carbon_shape = Shape::new(ShapeType::Rectangle, 4500000, 2700000, 1800000, 800000)
1032 .with_fill(ShapeFill::new(themes::CARBON.primary))
1033 .with_text("Carbon");
1034
1035 slides.push(
1036 SlideContent::new("Theme Color Palettes")
1037 .layout(SlideLayout::TitleAndContent)
1038 .title_color("1F497D")
1039 .title_bold(true)
1040 .add_shape(corporate_shape)
1041 .add_shape(modern_shape)
1042 .add_shape(vibrant_shape)
1043 .add_shape(dark_shape)
1044 .add_shape(nature_shape)
1045 .add_shape(tech_shape)
1046 .add_shape(carbon_shape)
1047 );
1048
1049 // =========================================================================
1050 // SLIDE 29: Material & Carbon Design Colors (NEW v0.2.1)
1051 // =========================================================================
1052 println!("🌈 Slide 29: Material & Carbon Colors (NEW)");
1053
1054 // Material Design colors
1055 let material_red = Shape::new(ShapeType::Rectangle, 500000, 1600000, 1200000, 600000)
1056 .with_fill(ShapeFill::new(colors::MATERIAL_RED))
1057 .with_text("M-Red");
1058
1059 let material_blue = Shape::new(ShapeType::Rectangle, 1900000, 1600000, 1200000, 600000)
1060 .with_fill(ShapeFill::new(colors::MATERIAL_BLUE))
1061 .with_text("M-Blue");
1062
1063 let material_green = Shape::new(ShapeType::Rectangle, 3300000, 1600000, 1200000, 600000)
1064 .with_fill(ShapeFill::new(colors::MATERIAL_GREEN))
1065 .with_text("M-Green");
1066
1067 let material_orange = Shape::new(ShapeType::Rectangle, 4700000, 1600000, 1200000, 600000)
1068 .with_fill(ShapeFill::new(colors::MATERIAL_ORANGE))
1069 .with_text("M-Orange");
1070
1071 let material_purple = Shape::new(ShapeType::Rectangle, 6100000, 1600000, 1200000, 600000)
1072 .with_fill(ShapeFill::new(colors::MATERIAL_PURPLE))
1073 .with_text("M-Purple");
1074
1075 // Carbon Design colors
1076 let carbon_blue = Shape::new(ShapeType::Rectangle, 500000, 2500000, 1200000, 600000)
1077 .with_fill(ShapeFill::new(colors::CARBON_BLUE_60))
1078 .with_text("C-Blue");
1079
1080 let carbon_green = Shape::new(ShapeType::Rectangle, 1900000, 2500000, 1200000, 600000)
1081 .with_fill(ShapeFill::new(colors::CARBON_GREEN_50))
1082 .with_text("C-Green");
1083
1084 let carbon_red = Shape::new(ShapeType::Rectangle, 3300000, 2500000, 1200000, 600000)
1085 .with_fill(ShapeFill::new(colors::CARBON_RED_60))
1086 .with_text("C-Red");
1087
1088 let carbon_purple = Shape::new(ShapeType::Rectangle, 4700000, 2500000, 1200000, 600000)
1089 .with_fill(ShapeFill::new(colors::CARBON_PURPLE_60))
1090 .with_text("C-Purple");
1091
1092 let carbon_gray = Shape::new(ShapeType::Rectangle, 6100000, 2500000, 1200000, 600000)
1093 .with_fill(ShapeFill::new(colors::CARBON_GRAY_100))
1094 .with_text("C-Gray");
1095
1096 slides.push(
1097 SlideContent::new("Material & Carbon Design Colors")
1098 .layout(SlideLayout::TitleAndContent)
1099 .title_color("1F497D")
1100 .title_bold(true)
1101 .add_shape(material_red)
1102 .add_shape(material_blue)
1103 .add_shape(material_green)
1104 .add_shape(material_orange)
1105 .add_shape(material_purple)
1106 .add_shape(carbon_blue)
1107 .add_shape(carbon_green)
1108 .add_shape(carbon_red)
1109 .add_shape(carbon_purple)
1110 .add_shape(carbon_gray)
1111 );
1112
1113 // =========================================================================
1114 // SLIDE 30: Image from Base64 (NEW v0.2.1)
1115 // =========================================================================
1116 println!("🖼️ Slide 30: Image from Base64 (NEW)");
1117
1118 // 1x1 red PNG pixel in base64
1119 let _red_pixel_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==";
1120
1121 // Create image from base64 (demonstrating the API)
1122 let _base64_image = ImageBuilder::from_base64(_red_pixel_base64, 914400, 914400, "PNG")
1123 .position(4000000, 2500000)
1124 .build();
1125
1126 slides.push(
1127 SlideContent::new("Image Loading - New Methods")
1128 .layout(SlideLayout::TitleAndContent)
1129 .title_color("1F497D")
1130 .title_bold(true)
1131 .add_bullet("Image::new(path) - Load from file path")
1132 .add_bullet("Image::from_base64(data) - Load from base64 string")
1133 .add_bullet("Image::from_bytes(data) - Load from raw bytes")
1134 .add_bullet("ImageBuilder for fluent API configuration")
1135 .add_bullet("Built-in base64 decoder (no external deps)")
1136 .content_size(24)
1137 );
1138
1139 // =========================================================================
1140 // SLIDE 31: Feature Summary (NEW v0.2.1)
1141 // =========================================================================
1142 println!("📋 Slide 31: v0.2.1 Feature Summary (NEW)");
1143
1144 slides.push(
1145 SlideContent::new("New Features in v0.2.1")
1146 .layout(SlideLayout::TitleAndContent)
1147 .title_color("1F497D")
1148 .title_bold(true)
1149 .add_numbered("BulletStyle: Number, Letter, Roman, Custom")
1150 .add_numbered("TextFormat: Strikethrough, Highlight")
1151 .add_numbered("TextFormat: Subscript, Superscript")
1152 .add_numbered("Font size presets in prelude")
1153 .add_numbered("Image::from_base64 and from_bytes")
1154 .add_numbered("Theme color palettes (7 themes)")
1155 .add_numbered("Material & Carbon Design colors")
1156 .content_size(24)
1157 );
1158
1159 // =========================================================================
1160 // SLIDE 32: Slide Show Settings - Comparison Table (REAL: embedded in presProps.xml)
1161 // =========================================================================
1162 println!("🎬 Slide 34: Slide Show Settings (Visual)");
1163
1164 let show_speaker = SlideShowSettings::new().pen_color(PenColor::red());
1165 let show_kiosk = SlideShowSettings::kiosk();
1166 let _show_range = SlideShowSettings::new()
1167 .show_type(ShowType::Browsed)
1168 .slide_range(SlideRange::Range { start: 1, end: 10 })
1169 .without_animation(true);
1170 let _speaker_xml = show_speaker.to_xml();
1171 let _kiosk_xml = show_kiosk.to_xml();
1172
1173 let show_table = TableBuilder::new(vec![2000000, 2000000, 2000000, 2000000])
1174 .add_row(TableRow::new(vec![
1175 TableCell::new("Setting").bold().background_color("1F4E79").text_color("FFFFFF"),
1176 TableCell::new("Speaker").bold().background_color("4472C4").text_color("FFFFFF"),
1177 TableCell::new("Kiosk").bold().background_color("ED7D31").text_color("FFFFFF"),
1178 TableCell::new("Browsed").bold().background_color("70AD47").text_color("FFFFFF"),
1179 ]))
1180 .add_row(TableRow::new(vec![
1181 TableCell::new("Loop").bold().background_color("D6E4F0"),
1182 TableCell::new("No"), TableCell::new("Yes").bold().text_color("2E7D32"),
1183 TableCell::new("No"),
1184 ]))
1185 .add_row(TableRow::new(vec![
1186 TableCell::new("Narration").bold().background_color("D6E4F0"),
1187 TableCell::new("Yes"), TableCell::new("No").text_color("C62828"),
1188 TableCell::new("Yes"),
1189 ]))
1190 .add_row(TableRow::new(vec![
1191 TableCell::new("Animation").bold().background_color("D6E4F0"),
1192 TableCell::new("Yes"), TableCell::new("Yes"),
1193 TableCell::new("No").text_color("C62828"),
1194 ]))
1195 .add_row(TableRow::new(vec![
1196 TableCell::new("Timings").bold().background_color("D6E4F0"),
1197 TableCell::new("Yes"), TableCell::new("Auto"),
1198 TableCell::new("Yes"),
1199 ]))
1200 .add_row(TableRow::new(vec![
1201 TableCell::new("Slide Range").bold().background_color("D6E4F0"),
1202 TableCell::new("All"), TableCell::new("All"),
1203 TableCell::new("1-10"),
1204 ]))
1205 .add_row(TableRow::new(vec![
1206 TableCell::new("Pen Color").bold().background_color("D6E4F0"),
1207 TableCell::new("Red").text_color("FF0000"),
1208 TableCell::new("Red").text_color("FF0000"),
1209 TableCell::new("Red").text_color("FF0000"),
1210 ]))
1211 .position(300000, 1600000)
1212 .build();
1213
1214 // Mode icons
1215 let icon_speaker = Shape::new(ShapeType::RoundedRectangle, 300000, 4200000, 2500000, 600000)
1216 .with_fill(ShapeFill::new("4472C4"))
1217 .with_text("Speaker: Full control");
1218 let icon_kiosk = Shape::new(ShapeType::RoundedRectangle, 3100000, 4200000, 2500000, 600000)
1219 .with_fill(ShapeFill::new("ED7D31"))
1220 .with_text("Kiosk: Auto-loop");
1221 let icon_browsed = Shape::new(ShapeType::RoundedRectangle, 5900000, 4200000, 2500000, 600000)
1222 .with_fill(ShapeFill::new("70AD47"))
1223 .with_text("Browsed: Scrollbar");
1224
1225 slides.push(
1226 SlideContent::new("Slide Show Settings - Mode Comparison")
1227 .table(show_table)
1228 .add_shape(icon_speaker)
1229 .add_shape(icon_kiosk)
1230 .add_shape(icon_browsed)
1231 .title_color("1F497D")
1232 .title_bold(true)
1233 );
1234
1235 // =========================================================================
1236 // SLIDE 35: Print Settings - Visual Handout Grid
1237 // =========================================================================
1238 println!("🖨️ Slide 35: Print Settings & Handouts (Visual)");
1239
1240 let print = PrintSettings::new()
1241 .print_what(PrintWhat::Handouts)
1242 .color_mode(PrintColorMode::Grayscale)
1243 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1244 .frame_slides(true)
1245 .header("Q1 2025 Strategy Review")
1246 .footer("Confidential - Internal Use Only")
1247 .print_date(true)
1248 .print_page_numbers(true);
1249 let _prnpr_xml = print.to_prnpr_xml();
1250 let _handout_xml = print.to_handout_master_xml();
1251
1252 // Visual: 6-slide handout grid (2 cols x 3 rows)
1253 let hdr = Shape::new(ShapeType::Rectangle, 300000, 1500000, 4200000, 300000)
1254 .with_fill(ShapeFill::new("E7E6E6"))
1255 .with_text("Q1 2025 Strategy Review");
1256 // Row 1
1257 let s1 = Shape::new(ShapeType::Rectangle, 400000, 2000000, 1800000, 1100000)
1258 .with_line(ShapeLine::new("999999", 12700))
1259 .with_text("Slide 1");
1260 let s2 = Shape::new(ShapeType::Rectangle, 2500000, 2000000, 1800000, 1100000)
1261 .with_line(ShapeLine::new("999999", 12700))
1262 .with_text("Slide 2");
1263 // Row 2
1264 let s3 = Shape::new(ShapeType::Rectangle, 400000, 3200000, 1800000, 1100000)
1265 .with_line(ShapeLine::new("999999", 12700))
1266 .with_text("Slide 3");
1267 let s4 = Shape::new(ShapeType::Rectangle, 2500000, 3200000, 1800000, 1100000)
1268 .with_line(ShapeLine::new("999999", 12700))
1269 .with_text("Slide 4");
1270 // Row 3
1271 let s5 = Shape::new(ShapeType::Rectangle, 400000, 4400000, 1800000, 1100000)
1272 .with_line(ShapeLine::new("999999", 12700))
1273 .with_text("Slide 5");
1274 let s6 = Shape::new(ShapeType::Rectangle, 2500000, 4400000, 1800000, 1100000)
1275 .with_line(ShapeLine::new("999999", 12700))
1276 .with_text("Slide 6");
1277 let ftr = Shape::new(ShapeType::Rectangle, 300000, 5600000, 4200000, 300000)
1278 .with_fill(ShapeFill::new("E7E6E6"))
1279 .with_text("Confidential - Internal Use Only");
1280
1281 // Settings summary table on the right
1282 let print_table = TableBuilder::new(vec![1800000, 2000000])
1283 .add_row(TableRow::new(vec![
1284 TableCell::new("Print Settings").bold().background_color("1F4E79").text_color("FFFFFF"),
1285 TableCell::new("").background_color("1F4E79"),
1286 ]))
1287 .add_row(TableRow::new(vec![
1288 TableCell::new("Print What").bold().background_color("D6E4F0"),
1289 TableCell::new("Handouts"),
1290 ]))
1291 .add_row(TableRow::new(vec![
1292 TableCell::new("Color Mode").bold().background_color("D6E4F0"),
1293 TableCell::new("Grayscale"),
1294 ]))
1295 .add_row(TableRow::new(vec![
1296 TableCell::new("Layout").bold().background_color("D6E4F0"),
1297 TableCell::new("6 slides/page"),
1298 ]))
1299 .add_row(TableRow::new(vec![
1300 TableCell::new("Frame Slides").bold().background_color("D6E4F0"),
1301 TableCell::new("Yes"),
1302 ]))
1303 .add_row(TableRow::new(vec![
1304 TableCell::new("Date").bold().background_color("D6E4F0"),
1305 TableCell::new("Yes"),
1306 ]))
1307 .add_row(TableRow::new(vec![
1308 TableCell::new("Page Numbers").bold().background_color("D6E4F0"),
1309 TableCell::new("Yes"),
1310 ]))
1311 .position(5000000, 1800000)
1312 .build();
1313
1314 slides.push(
1315 SlideContent::new("Print Handout - 6 Slides Per Page")
1316 .table(print_table)
1317 .add_shape(hdr)
1318 .add_shape(s1).add_shape(s2)
1319 .add_shape(s3).add_shape(s4)
1320 .add_shape(s5).add_shape(s6)
1321 .add_shape(ftr)
1322 .title_color("1F497D")
1323 .title_bold(true)
1324 );
1325
1326 // =========================================================================
1327 // SLIDE 36: Advanced Table Merging - Actual Merged Table
1328 // =========================================================================
1329 println!("📊 Slide 36: Advanced Table Merging (Visual)");
1330
1331 // Use TableMergeMap to compute states, then build a visual table
1332 let mut merge_map = TableMergeMap::new(5, 4);
1333 merge_map.merge_cells(0, 0, 1, 4).unwrap(); // Title row spans all 4 cols
1334 merge_map.merge_cells(1, 0, 2, 1).unwrap(); // "Products" spans 2 rows
1335 merge_map.merge_cells(3, 0, 2, 1).unwrap(); // "Services" spans 2 rows
1336
1337 // Show merge state labels
1338 let state_00 = merge_map.cell_state(0, 0); // Anchor gridSpan=4
1339 let state_01 = merge_map.cell_state(0, 1); // HMerge
1340 let state_10 = merge_map.cell_state(1, 0); // Anchor rowSpan=2
1341 let state_20 = merge_map.cell_state(2, 0); // VMerge
1342 println!(" ├── (0,0): {}", state_00.to_xml_attrs().trim());
1343 println!(" ├── (0,1): {}", state_01.to_xml_attrs().trim());
1344 println!(" ├── (1,0): {}", state_10.to_xml_attrs().trim());
1345 println!(" └── (2,0): {}", state_20.to_xml_attrs().trim());
1346
1347 // Build the table with REAL merge attributes (gridSpan, rowSpan, hMerge, vMerge)
1348 let merge_table = TableBuilder::new(vec![1500000, 2000000, 2000000, 2000000])
1349 .add_row(TableRow::new(vec![
1350 TableCell::new("Q1 2025 Revenue Report").bold().background_color("1F4E79").text_color("FFFFFF").grid_span(4),
1351 TableCell::new("").background_color("1F4E79").h_merge(),
1352 TableCell::new("").background_color("1F4E79").h_merge(),
1353 TableCell::new("").background_color("1F4E79").h_merge(),
1354 ]))
1355 .add_row(TableRow::new(vec![
1356 TableCell::new("Products").bold().background_color("BDD7EE").text_color("1F497D").row_span(2),
1357 TableCell::new("Hardware").background_color("E2EFDA"),
1358 TableCell::new("$450,000").text_color("2E7D32").align_right(),
1359 TableCell::new("+12%").bold().text_color("2E7D32").align_right(),
1360 ]))
1361 .add_row(TableRow::new(vec![
1362 TableCell::new("").background_color("BDD7EE").v_merge(),
1363 TableCell::new("Software").background_color("E2EFDA"),
1364 TableCell::new("$680,000").text_color("2E7D32").align_right(),
1365 TableCell::new("+25%").bold().text_color("2E7D32").align_right(),
1366 ]))
1367 .add_row(TableRow::new(vec![
1368 TableCell::new("Services").bold().background_color("FCE4D6").text_color("C65911").row_span(2),
1369 TableCell::new("Consulting").background_color("FFF2CC"),
1370 TableCell::new("$320,000").text_color("2E7D32").align_right(),
1371 TableCell::new("+8%").bold().text_color("2E7D32").align_right(),
1372 ]))
1373 .add_row(TableRow::new(vec![
1374 TableCell::new("").background_color("FCE4D6").v_merge(),
1375 TableCell::new("Support").background_color("FFF2CC"),
1376 TableCell::new("$190,000").text_color("2E7D32").align_right(),
1377 TableCell::new("+5%").bold().text_color("2E7D32").align_right(),
1378 ]))
1379 .position(300000, 1600000)
1380 .build();
1381
1382 // Legend shapes
1383 let legend_anchor = Shape::new(ShapeType::RoundedRectangle, 300000, 4400000, 2000000, 400000)
1384 .with_fill(ShapeFill::new("4472C4"))
1385 .with_text("Anchor (gridSpan/rowSpan)");
1386 let legend_hmerge = Shape::new(ShapeType::RoundedRectangle, 2500000, 4400000, 2000000, 400000)
1387 .with_fill(ShapeFill::new("ED7D31"))
1388 .with_text("hMerge (col covered)");
1389 let legend_vmerge = Shape::new(ShapeType::RoundedRectangle, 4700000, 4400000, 2000000, 400000)
1390 .with_fill(ShapeFill::new("70AD47"))
1391 .with_text("vMerge (row covered)");
1392 let legend_normal = Shape::new(ShapeType::RoundedRectangle, 6900000, 4400000, 2000000, 400000)
1393 .with_fill(ShapeFill::new("A5A5A5"))
1394 .with_text("Normal (no merge)");
1395
1396 slides.push(
1397 SlideContent::new("Advanced Table Merging - Merged Cells")
1398 .table(merge_table)
1399 .add_shape(legend_anchor)
1400 .add_shape(legend_hmerge)
1401 .add_shape(legend_vmerge)
1402 .add_shape(legend_normal)
1403 .title_color("1F497D")
1404 .title_bold(true)
1405 );
1406
1407 // =========================================================================
1408 // Build PresentationSettings with all advanced features
1409 // =========================================================================
1410 println!("\n⚙️ Building Presentation Settings...");
1411
1412 // Slide show settings (embedded in presProps.xml as <p:showPr>)
1413 let show_settings = SlideShowSettings::new()
1414 .show_type(ShowType::Speaker)
1415 .pen_color(PenColor::red())
1416 .use_timings(true);
1417 println!(" ├── Slide Show: Speaker mode, red pen, timings enabled");
1418 println!(" │ └── XML: {} bytes", show_settings.to_xml().len());
1419
1420 // Print settings (embedded in presProps.xml as <p:prnPr>)
1421 let print_settings = PrintSettings::new()
1422 .print_what(PrintWhat::Handouts)
1423 .color_mode(PrintColorMode::Grayscale)
1424 .handout_layout(GenHandoutLayout::SlidesPerPage6)
1425 .frame_slides(true)
1426 .header("Q1 2025 Strategy Review")
1427 .footer("Confidential - Internal Use Only")
1428 .print_date(true)
1429 .print_page_numbers(true);
1430 println!(" └── Print: Handouts, 6/page, grayscale, framed");
1431 println!(" └── XML: {} bytes", print_settings.to_prnpr_xml().len());
1432
1433 let pres_settings = PresentationSettings::new()
1434 .slide_show(show_settings)
1435 .print(print_settings);
1436 println!(" All settings configured → presProps.xml");
1437
1438 // =========================================================================
1439 // Generate PPTX with real integrated features
1440 // =========================================================================
1441 println!("\n📦 Generating PPTX with integrated features...");
1442 let pptx_data = create_pptx_with_settings(
1443 "PPTX-RS Element Showcase",
1444 slides.clone(),
1445 Some(pres_settings),
1446 )?;
1447 fs::write("comprehensive_demo.pptx", &pptx_data)?;
1448 println!(" ✓ Created comprehensive_demo.pptx ({} slides, {} bytes)",
1449 slides.len(), pptx_data.len());
1450
1451 // =========================================================================
1452 // Package Analysis - Demonstrate Reading
1453 // =========================================================================
1454 println!("\n📖 Package Analysis (Read Capability):");
1455
1456 let package = Package::open("comprehensive_demo.pptx")?;
1457 let paths = package.part_paths();
1458
1459 let slide_count = paths.iter()
1460 .filter(|p| p.starts_with("ppt/slides/slide") && p.ends_with(".xml"))
1461 .count();
1462
1463 println!(" ├── Total parts: {}", package.part_count());
1464 println!(" ├── Slides: {}", slide_count);
1465 println!(" └── Package opened and analyzed successfully");
1466
1467 // =========================================================================
1468 // NEW: Parts API Demonstration
1469 // =========================================================================
1470 println!("\n🧩 Parts API Demonstration:");
1471
1472 // SlideLayoutPart - 11 layout types
1473 println!(" ┌── SlideLayoutPart (11 layout types):");
1474 let layouts = [
1475 LayoutType::Title,
1476 LayoutType::TitleAndContent,
1477 LayoutType::SectionHeader,
1478 LayoutType::TwoContent,
1479 LayoutType::Comparison,
1480 LayoutType::TitleOnly,
1481 LayoutType::Blank,
1482 LayoutType::ContentWithCaption,
1483 LayoutType::PictureWithCaption,
1484 LayoutType::TitleAndVerticalText,
1485 LayoutType::VerticalTitleAndText,
1486 ];
1487 for (i, layout_type) in layouts.iter().enumerate() {
1488 let layout = SlideLayoutPart::new(i + 1, *layout_type);
1489 if i < 3 {
1490 println!(" │ ├── {}: {} ({})", i + 1, layout_type.name(), layout.path());
1491 }
1492 }
1493 println!(" │ └── ... and {} more layout types", layouts.len() - 3);
1494
1495 // SlideMasterPart
1496 println!(" ├── SlideMasterPart:");
1497 let mut master = SlideMasterPart::new(1);
1498 master.set_name("Custom Master");
1499 master.add_layout_rel_id("rId2");
1500 master.add_layout_rel_id("rId3");
1501 println!(" │ ├── Name: {}", master.name());
1502 println!(" │ ├── Path: {}", master.path());
1503 println!(" │ └── Layouts: {} linked", master.layout_rel_ids().len());
1504
1505 // ThemePart - Colors and Fonts
1506 println!(" ├── ThemePart (colors & fonts):");
1507 let mut theme = ThemePart::new(1);
1508 theme.set_name("Corporate Theme");
1509 theme.set_major_font("Arial");
1510 theme.set_minor_font("Calibri");
1511 theme.set_color("accent1", "FF5733");
1512 theme.set_color("accent2", "33FF57");
1513 let theme_xml = theme.to_xml()?;
1514 println!(" │ ├── Name: {}", theme.name());
1515 println!(" │ ├── Major Font: Arial");
1516 println!(" │ ├── Minor Font: Calibri");
1517 println!(" │ └── XML size: {} bytes", theme_xml.len());
1518
1519 // NotesSlidePart - Speaker notes
1520 println!(" ├── NotesSlidePart (speaker notes):");
1521 let notes = NotesSlidePart::with_text(1, "Remember to:\n- Introduce yourself\n- Explain the agenda\n- Ask for questions");
1522 let notes_xml = notes.to_xml()?;
1523 println!(" │ ├── Path: {}", notes.path());
1524 println!(" │ ├── Text: \"{}...\"", ¬es.notes_text()[..20.min(notes.notes_text().len())]);
1525 println!(" │ └── XML size: {} bytes", notes_xml.len());
1526
1527 // AppPropertiesPart - Application metadata
1528 println!(" ├── AppPropertiesPart (metadata):");
1529 let mut app_props = AppPropertiesPart::new();
1530 app_props.set_company("Acme Corporation");
1531 app_props.set_slides(slides.len() as u32);
1532 let app_xml = app_props.to_xml()?;
1533 println!(" │ ├── Company: Acme Corporation");
1534 println!(" │ ├── Slides: {}", slides.len());
1535 println!(" │ └── XML size: {} bytes", app_xml.len());
1536
1537 // MediaPart - Video/Audio formats
1538 println!(" ├── MediaPart (10 media formats):");
1539 println!(" │ ├── Video: mp4, webm, avi, wmv, mov");
1540 println!(" │ ├── Audio: mp3, wav, wma, m4a, ogg");
1541 let sample_media = MediaPart::new(1, MediaFormat::Mp4, vec![0; 100]);
1542 println!(" │ └── Sample: {} ({})", sample_media.path(), sample_media.format().mime_type());
1543
1544 // TablePart - Table with formatting
1545 println!(" ├── TablePart (cell formatting):");
1546 let table_part = TablePart::new()
1547 .add_row(TableRowPart::new(vec![
1548 TableCellPart::new("Header 1").bold().background("4472C4"),
1549 TableCellPart::new("Header 2").bold().background("4472C4"),
1550 ]))
1551 .add_row(TableRowPart::new(vec![
1552 TableCellPart::new("Data 1").color("333333"),
1553 TableCellPart::new("Data 2").italic(),
1554 ]))
1555 .position(EMU_PER_INCH, EMU_PER_INCH * 2)
1556 .size(EMU_PER_INCH * 6, EMU_PER_INCH * 2);
1557 let table_xml = table_part.to_slide_xml(10);
1558 println!(" │ ├── Rows: {}", table_part.rows.len());
1559 println!(" │ ├── Features: bold, italic, colors, backgrounds");
1560 println!(" │ └── XML size: {} bytes", table_xml.len());
1561
1562 // ContentTypesPart
1563 println!(" └── ContentTypesPart:");
1564 let mut content_types = ContentTypesPart::new();
1565 content_types.add_presentation();
1566 content_types.add_slide(1);
1567 content_types.add_slide_layout(1);
1568 content_types.add_slide_master(1);
1569 content_types.add_theme(1);
1570 content_types.add_core_properties();
1571 content_types.add_app_properties();
1572 let ct_xml = content_types.to_xml()?;
1573 println!(" ├── Path: {}", content_types.path());
1574 println!(" └── XML size: {} bytes", ct_xml.len());
1575
1576 // =========================================================================
1577 // NEW: Elements API Demonstration
1578 // =========================================================================
1579 println!("\n🎨 Elements API Demonstration:");
1580
1581 // Color types
1582 println!(" ┌── Color Types:");
1583 let rgb = RgbColor::new(255, 87, 51);
1584 let rgb_hex = RgbColor::from_hex("#4472C4").unwrap();
1585 let scheme = SchemeColor::Accent1;
1586 let color = Color::rgb(100, 149, 237);
1587 println!(" │ ├── RgbColor::new(255, 87, 51) → {}", rgb.to_hex());
1588 println!(" │ ├── RgbColor::from_hex(\"#4472C4\") → {}", rgb_hex.to_hex());
1589 println!(" │ ├── SchemeColor::Accent1 → {}", scheme.as_str());
1590 println!(" │ └── Color::rgb(100, 149, 237) → XML: {}", color.to_xml().chars().take(30).collect::<String>());
1591
1592 // Position and Size
1593 println!(" ├── Position & Size (EMU units):");
1594 let pos = Position::from_inches(1.0, 2.0);
1595 let size = Size::from_inches(4.0, 3.0);
1596 println!(" │ ├── Position::from_inches(1.0, 2.0) → x={}, y={}", pos.x, pos.y);
1597 println!(" │ ├── Size::from_inches(4.0, 3.0) → w={}, h={}", size.width, size.height);
1598 println!(" │ └── EMU_PER_INCH = {}", EMU_PER_INCH);
1599
1600 // Transform
1601 println!(" └── Transform (position + size + rotation):");
1602 let transform = Transform::from_inches(1.0, 1.5, 3.0, 2.0).with_rotation(45.0);
1603 let transform_xml = transform.to_xml();
1604 println!(" ├── Transform::from_inches(1.0, 1.5, 3.0, 2.0)");
1605 println!(" ├── .with_rotation(45.0)");
1606 println!(" └── XML: {}...", &transform_xml[..50.min(transform_xml.len())]);
1607
1608 // =========================================================================
1609 // NEW: Advanced Features Demonstration
1610 // =========================================================================
1611 println!("\n🚀 Advanced Features Demonstration:");
1612
1613 // -------------------------------------------------------------------------
1614 // Complex Table Examples
1615 // -------------------------------------------------------------------------
1616 println!(" ┌── Complex Table Examples:");
1617
1618 // Example 1: Financial Report Table
1619 println!(" │ ┌── Financial Report Table (5x4 with formatting):");
1620 let financial_table = TablePart::new()
1621 .add_row(TableRowPart::new(vec![
1622 TableCellPart::new("Q1 2024 Financial Summary")
1623 .col_span(4)
1624 .bold()
1625 .center()
1626 .background("1F4E79")
1627 .color("FFFFFF")
1628 .font_size(14)
1629 .font("Arial Black"),
1630 ]))
1631 .add_row(TableRowPart::new(vec![
1632 TableCellPart::new("Category").bold().center().background("2E75B6").color("FFFFFF"),
1633 TableCellPart::new("Revenue").bold().center().background("2E75B6").color("FFFFFF"),
1634 TableCellPart::new("Expenses").bold().center().background("2E75B6").color("FFFFFF"),
1635 TableCellPart::new("Profit").bold().center().background("2E75B6").color("FFFFFF"),
1636 ]))
1637 .add_row(TableRowPart::new(vec![
1638 TableCellPart::new("Product Sales").align(HorizontalAlign::Left),
1639 TableCellPart::new("$1,250,000").align(HorizontalAlign::Right).color("2E7D32"),
1640 TableCellPart::new("$450,000").align(HorizontalAlign::Right).color("C62828"),
1641 TableCellPart::new("$800,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1642 ]))
1643 .add_row(TableRowPart::new(vec![
1644 TableCellPart::new("Services").align(HorizontalAlign::Left),
1645 TableCellPart::new("$890,000").align(HorizontalAlign::Right).color("2E7D32"),
1646 TableCellPart::new("$320,000").align(HorizontalAlign::Right).color("C62828"),
1647 TableCellPart::new("$570,000").align(HorizontalAlign::Right).bold().color("2E7D32"),
1648 ]))
1649 .add_row(TableRowPart::new(vec![
1650 TableCellPart::new("Total").bold().background("E7E6E6"),
1651 TableCellPart::new("$2,140,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1652 TableCellPart::new("$770,000").bold().align(HorizontalAlign::Right).background("E7E6E6"),
1653 TableCellPart::new("$1,370,000").bold().align(HorizontalAlign::Right).background("C6EFCE").color("006100"),
1654 ]))
1655 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1656 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 3);
1657 let fin_xml = financial_table.to_slide_xml(100);
1658 println!(" │ │ ├── Merged header spanning 4 columns");
1659 println!(" │ │ ├── Color-coded values (green=positive, red=negative)");
1660 println!(" │ │ ├── Custom fonts and sizes");
1661 println!(" │ │ └── XML: {} bytes", fin_xml.len());
1662
1663 // Example 2: Comparison Matrix
1664 println!(" │ ├── Comparison Matrix (features vs products):");
1665 let _matrix_table = TablePart::new()
1666 .add_row(TableRowPart::new(vec![
1667 TableCellPart::new("Feature").bold().center().background("4472C4").color("FFFFFF"),
1668 TableCellPart::new("Basic").bold().center().background("4472C4").color("FFFFFF"),
1669 TableCellPart::new("Pro").bold().center().background("4472C4").color("FFFFFF"),
1670 TableCellPart::new("Enterprise").bold().center().background("4472C4").color("FFFFFF"),
1671 ]))
1672 .add_row(TableRowPart::new(vec![
1673 TableCellPart::new("Storage").align(HorizontalAlign::Left),
1674 TableCellPart::new("5 GB").center(),
1675 TableCellPart::new("50 GB").center(),
1676 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1677 ]))
1678 .add_row(TableRowPart::new(vec![
1679 TableCellPart::new("Users").align(HorizontalAlign::Left),
1680 TableCellPart::new("1").center(),
1681 TableCellPart::new("10").center(),
1682 TableCellPart::new("Unlimited").center().bold().color("2E7D32"),
1683 ]))
1684 .add_row(TableRowPart::new(vec![
1685 TableCellPart::new("Support").align(HorizontalAlign::Left),
1686 TableCellPart::new("Email").center(),
1687 TableCellPart::new("24/7 Chat").center(),
1688 TableCellPart::new("Dedicated").center().bold().color("2E7D32"),
1689 ]))
1690 .add_row(TableRowPart::new(vec![
1691 TableCellPart::new("Price/mo").bold().background("F2F2F2"),
1692 TableCellPart::new("$9").center().bold().background("F2F2F2"),
1693 TableCellPart::new("$29").center().bold().background("F2F2F2"),
1694 TableCellPart::new("$99").center().bold().background("F2F2F2"),
1695 ]));
1696 println!(" │ │ └── 5x4 matrix with alternating styles");
1697
1698 // Example 3: Schedule/Timeline Table
1699 println!(" │ └── Schedule Table (with row spans):");
1700 let _schedule_table = TablePart::new()
1701 .add_row(TableRowPart::new(vec![
1702 TableCellPart::new("Time").bold().center().background("70AD47").color("FFFFFF"),
1703 TableCellPart::new("Monday").bold().center().background("70AD47").color("FFFFFF"),
1704 TableCellPart::new("Tuesday").bold().center().background("70AD47").color("FFFFFF"),
1705 ]))
1706 .add_row(TableRowPart::new(vec![
1707 TableCellPart::new("9:00 AM").center().background("E2EFDA"),
1708 TableCellPart::new("Team Standup").center().row_span(2).valign(VerticalAlign::Middle).background("BDD7EE"),
1709 TableCellPart::new("Code Review").center(),
1710 ]))
1711 .add_row(TableRowPart::new(vec![
1712 TableCellPart::new("10:00 AM").center().background("E2EFDA"),
1713 TableCellPart::merged(),
1714 TableCellPart::new("Sprint Planning").center().background("FCE4D6"),
1715 ]));
1716 println!(" │ └── Row spans for multi-hour events");
1717
1718 // -------------------------------------------------------------------------
1719 // Complex Animation Sequences
1720 // -------------------------------------------------------------------------
1721 println!(" ├── Complex Animation Sequences:");
1722
1723 // Sequence 1: Title entrance with staggered content
1724 println!(" │ ┌── Staggered Entrance Sequence:");
1725 let title_anim = Animation::new(2, AnimationEffect::Fade)
1726 .trigger(AnimationTrigger::OnClick)
1727 .duration(500);
1728 let content1 = Animation::new(3, AnimationEffect::FlyIn)
1729 .trigger(AnimationTrigger::AfterPrevious)
1730 .direction(AnimationDirection::Left)
1731 .duration(400)
1732 .delay(200);
1733 let content2 = Animation::new(4, AnimationEffect::FlyIn)
1734 .trigger(AnimationTrigger::AfterPrevious)
1735 .direction(AnimationDirection::Left)
1736 .duration(400)
1737 .delay(100);
1738 let content3 = Animation::new(5, AnimationEffect::FlyIn)
1739 .trigger(AnimationTrigger::AfterPrevious)
1740 .direction(AnimationDirection::Left)
1741 .duration(400)
1742 .delay(100);
1743 let staggered = SlideAnimations::new()
1744 .add(title_anim)
1745 .add(content1)
1746 .add(content2)
1747 .add(content3)
1748 .transition(SlideTransition::new(TransitionEffect::Push).direction(AnimationDirection::Left).duration(750));
1749 let staggered_xml = staggered.to_timing_xml()?;
1750 println!(" │ │ ├── Title: Fade on click");
1751 println!(" │ │ ├── Content 1-3: FlyIn with 100ms stagger");
1752 println!(" │ │ ├── Transition: Push from left (750ms)");
1753 println!(" │ │ └── XML: {} bytes", staggered_xml.len());
1754
1755 // Sequence 2: Emphasis and exit
1756 println!(" │ ├── Emphasis + Exit Sequence:");
1757 let emphasis = Animation::new(6, AnimationEffect::Pulse)
1758 .trigger(AnimationTrigger::OnClick)
1759 .duration(1000)
1760 .repeat(3);
1761 let exit = Animation::new(6, AnimationEffect::FadeOut)
1762 .trigger(AnimationTrigger::AfterPrevious)
1763 .duration(500);
1764 let _emphasis_seq = SlideAnimations::new()
1765 .add(emphasis)
1766 .add(exit);
1767 println!(" │ │ ├── Pulse 3x on click, then fade out");
1768 println!(" │ │ └── Same shape, sequential effects");
1769
1770 // Sequence 3: Motion path
1771 println!(" │ └── Motion Path Animation:");
1772 let _motion = Animation::new(7, AnimationEffect::Lines)
1773 .trigger(AnimationTrigger::OnClick)
1774 .duration(2000);
1775 println!(" │ └── Custom path: Lines, Arcs, Turns, Loops");
1776
1777 // -------------------------------------------------------------------------
1778 // SmartArt Combinations
1779 // -------------------------------------------------------------------------
1780 println!(" ├── SmartArt Layout Examples:");
1781
1782 // Process flow
1783 println!(" │ ┌── Process Flow (5 steps):");
1784 let process = SmartArtPart::new(1, SmartArtLayout::BasicProcess)
1785 .add_items(vec!["Research", "Design", "Develop", "Test", "Deploy"])
1786 .position(EMU_PER_INCH / 2, EMU_PER_INCH * 2)
1787 .size(EMU_PER_INCH * 8, EMU_PER_INCH * 2);
1788 println!(" │ │ └── {} nodes in horizontal flow", process.nodes().len());
1789
1790 // Organization chart
1791 println!(" │ ├── Organization Chart:");
1792 let org = SmartArtPart::new(2, SmartArtLayout::OrgChart)
1793 .add_items(vec!["CEO", "CTO", "CFO", "VP Engineering", "VP Sales"]);
1794 println!(" │ │ └── Hierarchical structure with {} positions", org.nodes().len());
1795
1796 // Cycle diagram
1797 println!(" │ ├── Cycle Diagram:");
1798 let cycle = SmartArtPart::new(3, SmartArtLayout::BasicCycle)
1799 .add_items(vec!["Plan", "Do", "Check", "Act"]);
1800 println!(" │ │ └── PDCA cycle with {} phases", cycle.nodes().len());
1801
1802 // Venn diagram
1803 println!(" │ ├── Venn Diagram:");
1804 let _venn = SmartArtPart::new(4, SmartArtLayout::BasicVenn)
1805 .add_items(vec!["Skills", "Passion", "Market Need"]);
1806 println!(" │ │ └── 3-circle Venn for Ikigai concept");
1807
1808 // Pyramid
1809 println!(" │ └── Pyramid:");
1810 let pyramid = SmartArtPart::new(5, SmartArtLayout::BasicPyramid)
1811 .add_items(vec!["Self-Actualization", "Esteem", "Love/Belonging", "Safety", "Physiological"]);
1812 println!(" │ └── Maslow's hierarchy with {} levels", pyramid.nodes().len());
1813
1814 // -------------------------------------------------------------------------
1815 // 3D Model Configurations
1816 // -------------------------------------------------------------------------
1817 println!(" ├── 3D Model Configurations:");
1818
1819 // Product showcase
1820 println!(" │ ┌── Product Showcase:");
1821 let _product_3d = Model3DPart::new(1, Model3DFormat::Glb, vec![0; 100])
1822 .camera(CameraPreset::IsometricTopUp)
1823 .rotation(0.0, 45.0, 0.0)
1824 .zoom(1.2)
1825 .position(EMU_PER_INCH * 2, EMU_PER_INCH * 2)
1826 .size(EMU_PER_INCH * 4, EMU_PER_INCH * 4);
1827 println!(" │ │ ├── Camera: Isometric top-up view");
1828 println!(" │ │ ├── Rotation: 45° Y-axis for best angle");
1829 println!(" │ │ └── Zoom: 1.2x for detail");
1830
1831 // Architectural model
1832 println!(" │ ├── Architectural Model:");
1833 let _arch_3d = Model3DPart::new(2, Model3DFormat::Gltf, vec![0; 100])
1834 .camera(CameraPreset::Front)
1835 .rotation(15.0, -30.0, 0.0)
1836 .ambient_light("FFFFCC");
1837 println!(" │ │ ├── Camera: Front view with tilt");
1838 println!(" │ │ └── Ambient: Warm lighting (FFFFCC)");
1839
1840 // Technical diagram
1841 println!(" │ └── Technical Diagram:");
1842 let _tech_3d = Model3DPart::new(3, Model3DFormat::Obj, vec![0; 100])
1843 .camera(CameraPreset::IsometricOffAxis1Top)
1844 .rotation(0.0, 0.0, 0.0);
1845 println!(" │ └── Camera: Off-axis isometric for exploded view");
1846
1847 // -------------------------------------------------------------------------
1848 // Theme + Master + Layout Combination
1849 // -------------------------------------------------------------------------
1850 println!(" ├── Theme + Master + Layout Integration:");
1851
1852 // Corporate theme
1853 let mut corp_theme = ThemePart::new(1);
1854 corp_theme.set_name("Corporate Blue");
1855 corp_theme.set_major_font("Segoe UI");
1856 corp_theme.set_minor_font("Segoe UI Light");
1857 corp_theme.set_color("dk1", "000000");
1858 corp_theme.set_color("lt1", "FFFFFF");
1859 corp_theme.set_color("dk2", "1F497D");
1860 corp_theme.set_color("lt2", "EEECE1");
1861 corp_theme.set_color("accent1", "4472C4");
1862 corp_theme.set_color("accent2", "ED7D31");
1863 corp_theme.set_color("accent3", "A5A5A5");
1864 corp_theme.set_color("accent4", "FFC000");
1865 corp_theme.set_color("accent5", "5B9BD5");
1866 corp_theme.set_color("accent6", "70AD47");
1867 let theme_xml = corp_theme.to_xml()?;
1868 println!(" │ ├── Theme: Corporate Blue");
1869 println!(" │ │ ├── Fonts: Segoe UI / Segoe UI Light");
1870 println!(" │ │ ├── 12 color slots defined");
1871 println!(" │ │ └── XML: {} bytes", theme_xml.len());
1872
1873 // Master with multiple layouts
1874 let mut corp_master = SlideMasterPart::new(1);
1875 corp_master.set_name("Corporate Master");
1876 corp_master.add_layout_rel_id("rId2"); // Title
1877 corp_master.add_layout_rel_id("rId3"); // Title + Content
1878 corp_master.add_layout_rel_id("rId4"); // Section Header
1879 corp_master.add_layout_rel_id("rId5"); // Two Content
1880 corp_master.add_layout_rel_id("rId6"); // Comparison
1881 corp_master.add_layout_rel_id("rId7"); // Title Only
1882 corp_master.add_layout_rel_id("rId8"); // Blank
1883 println!(" │ └── Master: {} with {} layouts linked", corp_master.name(), corp_master.layout_rel_ids().len());
1884
1885 // -------------------------------------------------------------------------
1886 // VBA + Custom XML Integration
1887 // -------------------------------------------------------------------------
1888 println!(" ├── VBA + Custom XML Integration:");
1889
1890 // VBA with multiple modules
1891 let _vba_project = VbaProjectPart::new()
1892 .add_module(VbaModule::new("AutoRun", r#"
1893Sub Auto_Open()
1894 MsgBox "Welcome to the presentation!"
1895End Sub
1896
1897Sub NavigateToSlide(slideNum As Integer)
1898 SlideShowWindows(1).View.GotoSlide slideNum
1899End Sub
1900"#))
1901 .add_module(VbaModule::new("DataHelpers", r#"
1902Function GetCustomData(key As String) As String
1903 ' Read from Custom XML part
1904 GetCustomData = ActivePresentation.CustomXMLParts(1).SelectSingleNode("//" & key).Text
1905End Function
1906"#))
1907 .add_module(VbaModule::class("SlideController", r#"
1908Private currentSlide As Integer
1909
1910Public Sub NextSlide()
1911 currentSlide = currentSlide + 1
1912 NavigateToSlide currentSlide
1913End Sub
1914"#));
1915 println!(" │ ├── VBA Project:");
1916 println!(" │ │ ├── AutoRun: Auto_Open, NavigateToSlide");
1917 println!(" │ │ ├── DataHelpers: GetCustomData (reads Custom XML)");
1918 println!(" │ │ └── SlideController: Class for navigation");
1919
1920 // Custom XML with structured data
1921 let app_config = CustomXmlPart::new(1, "presentationConfig")
1922 .namespace("http://company.com/pptx/config")
1923 .property("version", "2.1.0")
1924 .property("author", "Demo User")
1925 .property("department", "Engineering")
1926 .property("confidentiality", "Internal")
1927 .property("lastModified", "2024-01-15T10:30:00Z");
1928 let config_xml = app_config.to_xml()?;
1929 println!(" │ └── Custom XML:");
1930 println!(" │ ├── Namespace: http://company.com/pptx/config");
1931 println!(" │ ├── Properties: version, author, department, etc.");
1932 println!(" │ └── XML: {} bytes", config_xml.len());
1933
1934 // -------------------------------------------------------------------------
1935 // Embedded Fonts with Variants
1936 // -------------------------------------------------------------------------
1937 println!(" ├── Embedded Font Collection:");
1938 let mut font_collection = EmbeddedFontCollection::new();
1939 font_collection.add("Corporate Sans", vec![0; 1000]);
1940 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Bold);
1941 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::Italic);
1942 font_collection.add_with_type("Corporate Sans", vec![0; 1000], FontEmbedType::BoldItalic);
1943 font_collection.add("Code Mono", vec![0; 800]);
1944 let fonts_xml = font_collection.to_xml();
1945 println!(" │ ├── Corporate Sans: Regular, Bold, Italic, BoldItalic");
1946 println!(" │ ├── Code Mono: Regular");
1947 println!(" │ ├── Total: {} font files", font_collection.len());
1948 println!(" │ └── XML: {} bytes", fonts_xml.len());
1949
1950 // -------------------------------------------------------------------------
1951 // Handout with Full Configuration
1952 // -------------------------------------------------------------------------
1953 println!(" └── Handout Master Configuration:");
1954 let handout = HandoutMasterPart::new()
1955 .layout(HandoutLayout::SlidesPerPage6)
1956 .header("Q1 2024 Strategy Review")
1957 .footer("Confidential - Internal Use Only");
1958 let handout_xml = handout.to_xml()?;
1959 println!(" ├── Layout: 6 slides per page");
1960 println!(" ├── Header: Q1 2024 Strategy Review");
1961 println!(" ├── Footer: Confidential - Internal Use Only");
1962 println!(" └── XML: {} bytes", handout_xml.len());
1963
1964 // =========================================================================
1965 // Summary
1966 // =========================================================================
1967 println!("\n╔══════════════════════════════════════════════════════════════╗");
1968 println!("║ Element Coverage Summary ║");
1969 println!("╠══════════════════════════════════════════════════════════════╣");
1970 println!("║ LAYOUTS (6 types): ║");
1971 println!("║ ✓ CenteredTitle ✓ TitleOnly ✓ TitleAndContent ║");
1972 println!("║ ✓ TitleAndBigContent ✓ TwoColumn ✓ Blank ║");
1973 println!("╠══════════════════════════════════════════════════════════════╣");
1974 println!("║ TEXT FORMATTING: ║");
1975 println!("║ ✓ Bold ✓ Italic ✓ Underline ║");
1976 println!("║ ✓ Font Size ✓ Font Color ✓ Title/Content styles ║");
1977 println!("╠══════════════════════════════════════════════════════════════╣");
1978 println!("║ TABLES: ║");
1979 println!("║ ✓ Multiple rows/columns ✓ Bold cells ✓ Background colors║");
1980 println!("║ ✓ Header styling ✓ Position control ║");
1981 println!("╠══════════════════════════════════════════════════════════════╣");
1982 println!("║ CHARTS: ║");
1983 println!("║ ✓ Bar Chart ✓ Line Chart ✓ Pie Chart ║");
1984 println!("║ ✓ Multiple series ✓ Categories ║");
1985 println!("╠══════════════════════════════════════════════════════════════╣");
1986 println!("║ SHAPES: ║");
1987 println!("║ ✓ Rectangle ✓ Ellipse ✓ RoundedRectangle ║");
1988 println!("║ ✓ Triangle ✓ Diamond ✓ Color fills ║");
1989 println!("║ ✓ Gradient fills ✓ Transparency ✓ Text in shapes ║");
1990 println!("╠══════════════════════════════════════════════════════════════╣");
1991 println!("║ CONNECTORS (NEW): ║");
1992 println!("║ ✓ Straight ✓ Elbow ✓ Curved ║");
1993 println!("║ ✓ Arrow types ✓ Dash styles ✓ Line colors/widths ║");
1994 println!("╠══════════════════════════════════════════════════════════════╣");
1995 println!("║ IMAGES: ║");
1996 println!("║ ✓ Image placeholders ✓ Position ✓ Dimensions ║");
1997 println!("╠══════════════════════════════════════════════════════════════╣");
1998 println!("║ PACKAGE: ║");
1999 println!("║ ✓ Create PPTX ✓ Read PPTX ✓ Analyze contents ║");
2000 println!("╠══════════════════════════════════════════════════════════════╣");
2001 println!("║ PARTS API (NEW): ║");
2002 println!("║ ✓ SlideLayoutPart (11 types) ✓ SlideMasterPart ║");
2003 println!("║ ✓ ThemePart (colors/fonts) ✓ NotesSlidePart ║");
2004 println!("║ ✓ AppPropertiesPart ✓ MediaPart (10 formats) ║");
2005 println!("║ ✓ TablePart (cell formatting) ✓ ContentTypesPart ║");
2006 println!("╠══════════════════════════════════════════════════════════════╣");
2007 println!("║ ELEMENTS API: ║");
2008 println!("║ ✓ RgbColor ✓ SchemeColor ✓ Color enum ║");
2009 println!("║ ✓ Position ✓ Size ✓ Transform ║");
2010 println!("║ ✓ EMU conversions (inches, cm, mm, pt) ║");
2011 println!("╠══════════════════════════════════════════════════════════════╣");
2012 println!("║ ADVANCED FEATURES (NEW): ║");
2013 println!("║ ✓ Animation (50+ effects) ✓ Transitions (27 types) ║");
2014 println!("║ ✓ SmartArt (25 layouts) ✓ 3D Models (GLB/GLTF/OBJ) ║");
2015 println!("║ ✓ VBA Macros (.pptm) ✓ Embedded Fonts ║");
2016 println!("║ ✓ Custom XML ✓ Handout Master ║");
2017 println!("║ ✓ Table borders/alignment ✓ Merged cells ║");
2018 println!("╠══════════════════════════════════════════════════════════════╣");
2019 println!("║ DIMENSION API (NEW): ║");
2020 println!("║ ✓ EMU / Inches / Cm / Pt / Ratio / Percent units ║");
2021 println!("║ ✓ from_dimensions() constructor ║");
2022 println!("║ ✓ Fluent .at() and .with_dimensions() chaining ║");
2023 println!("║ ✓ Mixed-unit positioning (e.g. inches + percent) ║");
2024 println!("╠══════════════════════════════════════════════════════════════╣");
2025 println!("║ Output: comprehensive_demo.pptx ({} slides, {} KB) ║",
2026 slides.len(), pptx_data.len() / 1024);
2027 println!("╚══════════════════════════════════════════════════════════════╝");
2028
2029 Ok(())
2030}Sourcepub fn with_col_span(self, span: u32) -> Self
pub fn with_col_span(self, span: u32) -> Self
Alias: set column span (gridSpan)
Sourcepub fn with_row_span(self, span: u32) -> Self
pub fn with_row_span(self, span: u32) -> Self
Alias: set row span
Sourcepub fn with_h_merge(self) -> Self
pub fn with_h_merge(self) -> Self
Alias: set horizontal merge flag
Sourcepub fn with_v_merge(self) -> Self
pub fn with_v_merge(self) -> Self
Alias: set vertical merge flag